2014-03-04 6 views
1

Как вы решаете, когда и как нарушать single responsability principle?Когда нарушать принцип единой ответственности?

Например, скажем, у меня есть сетевая камера со следующим интерфейсом (интерфейс продолжал глупо и «неправильно» для простоты):

class Camera 
{ 
    string user(); 
    void set_user(string user); 

    string password(); 
    void set_password(string password); 

    string url(); 
    void set_url(string url); 

    image take_snapshot(); 

    bool reboot(); 
} 

Это выглядит естественно, но это выглядит как класс камеры имеет 3 responsabilties: хранить метаданные, делать снимок, перезагружать. После SRP, вы могли бы написать это следующим образом:

class Camera 
{ 
    string user(); 
    void set_user(string user); 

    string password(); 
    void set_password(string password); 

    string url(); 
    void set_url(string url); 
} 

image take_snapshot(camera c); 
bool reboot_camera(camera c); 

Здесь питания аккуратно разделены по ОБЯЗАННОСТИ, но сейчас он очень похож на C с немыми и функцией структурами ... Возникает вопрос о том, зачем нам ООП в первую очередь.

Как вы балансируете между удобством и SRP?

[EDIT]

@stjin идея была показана в ответ на @John Zwinck

+1

«Когда нарушать принцип единой ответственности?» - редко ... –

+1

* Это выглядит естественным * не совсем: путь к большому количеству получателей/сеттеров:] Возможно, даже если вы это исправите, вам больше не нужно будет задавать этот вопрос. – stijn

+0

@stijn: это пример ... также я не вижу, как вы можете избежать этого в некоторых ситуациях, за исключением случаев, когда вы имеете в виду код в стиле C с немыми структурами и функциями, управляющими ими. – Silex

ответ

4

Я бы написать пример так:

class Session 
{ 
public: 
    Session(string url, string user, string password); 
}; 

class Camera 
{ 
public: 
    Camera(Session); 

    image take_snapshot(); 
    bool reboot(); 
}; 

Основная идея здесь заключается в разделении аутентификацию и определение сеанса/конечной точки (и, возможно, соединение) с помощью элементов управления камерой. Класс Camera теперь более точно моделирует настоящую камеру: у нее есть что-то вроде кнопки питания и кнопки спуска затвора. Виртуализация камеры находится в другом месте, сама по себе. Это также делает более очевидным, что делать, если кто-то хочет сделать сеанс USB для другой камеры и т. Д.

Вторичная идея состоит в том, что объекты создаются с действующим состоянием с самого начала. Здесь нет способа настроить камеру без пароля, например, вызов функции take_snapshot() без учетных данных просто невозможно. Конечно, учетные данные могут быть недействительными, но это может быть проверено каким-либо методом, который может быть вызван в одном из конструкторов.

В стороне, нет ничего плохого в бесплатных функциях. ООП переоценивается, мы все это знаем, и вы не должны испытывать никакой необходимости извиняться, если бесплатные функции работают в вашем случае использования. Dumb-структуры могут быть лучше, чем бессмысленные геттеры и сеттеры, особенно если вы не создаете повторно используемую библиотеку с требованиями совместимости ABI.

+0

IMO, свободные функции * улучшают * объектно-ориентированное программирование, потому что они добавляют еще один уровень доступности. Если метод работает только с публичными членами объекта и сам является членом класса, он все равно будет иметь доступ ко всем частным членам. Если это бесплатная функция, она имеет доступ только к тому, что необходимо для выполнения задачи, за которую она отвечает (игнорируйте «друг»). Свободные функции в одном пространстве имен можно считать частью интерфейса класса. – Excelcius

+0

@John Zwinck: хорошо, спасибо за пример и обоснование. Можете ли вы объяснить, что приходит на ум при выборе подхода «свободных функций» и подхода «ООП»? Я имею в виду, что альтернатива «бесплатных функций», по-видимому, является более чистой, чем SRP, почти все время. – Silex

+0

Я имею в виду, мой реальный вопрос заключается в том, где можно провести линию между удобным подходом «ООП» и «свободными функциями». Может быть, что-то вроде «Использовать ООП, когда он хорошо сочетается с концепцией реального мира, использовать свободные функции, когда вам нужно, чтобы он был более сложным»? – Silex