Твердые принципы действительно твердые? - PullRequest
38 голосов
/ 08 июня 2010

Шаблон дизайна, который обозначает первая буква в этом акрониме, - это принцип единой ответственности. Вот цитата:

принцип единоличной ответственности утверждает, что каждый объект должен иметь единственная ответственность, и это ответственность должна быть полностью инкапсулированный классом.

Это просто и понятно, пока мы не начнем кодировать. Предположим, у нас есть класс с четко определенной единственной ответственностью. Чтобы сериализовать экземпляры класса, нам нужно добавить в этот класс специальные атрибуты. Так что теперь у класса есть другая ответственность. Разве это не нарушает ПСП?

Давайте посмотрим другой пример - реализация интерфейса. Когда мы реализуем интерфейс, мы просто добавляем другие обязанности, например, распределяем его ресурсы или сравниваем его экземпляры или что-то подобное.

Итак, мой вопрос. Можно ли строго придерживаться SRP? Как это можно сделать?

Ответы [ 11 ]

70 голосов
/ 08 июня 2010

Как вы однажды обнаружите, ни один из самых известных принципов в разработке программного обеспечения не может быть выполнен на 100%.

Программирование часто сводится к компромиссу - абстрактная чистота в зависимости от размера кода, скорости и эффективности.

Вам просто нужно научиться находить правильный баланс: не позволяйте вашему приложению упасть в пропасть хаоса, но не связывайте себя множеством слоев абстракции.

13 голосов
/ 08 июня 2010

Я не думаю, что возможность сериализации или одноразового использования подразумевает множество обязанностей.

10 голосов
/ 08 июня 2010

Ну, я полагаю, первое, что нужно отметить, это то, что это всего лишь хорошие принципы разработки программного обеспечения - вы должны также принять суждение. Так что в этом смысле - нет, они не сплошные (!)

Я думаю, что вопрос, который вы задали, поднимает ключевой вопрос - как вы определяете единственную ответственность, которую должен иметь класс?

Важно не слишком зацикливаться на деталях при определении ответственности - просто потому, что класс делает много вещей в коде, не означает, что у него много обязанностей.

Однако, пожалуйста, придерживайтесь этого. Хотя это, вероятно, невозможно применить во всех случаях - это все же лучше, чем иметь в своем коде один «объект Бога» (Anti-Pattern).

Если у вас возникли проблемы с этим, я бы порекомендовал прочитать следующее:

  • Рефакторинг - Мартин Фаулер: Хотя речь идет, очевидно, о рефакторинге, эта книга также очень полезна для демонстрации того, как разбить проблемы на их логические части или обязанности - что является ключом к SRP. Эта книга также затрагивает другие принципы - однако она делает это намного менее академическим способом, чем вы, возможно, видели раньше.

  • Чистый код - Роберт Мартин: Кого лучше читать, чем величайшего представителя принципов ТВЕРДЫХ. Серьезно, я обнаружил, что это действительно полезная книга во всех областях мастерства программного обеспечения, а не только в принципах SOLID. Как и книга Фаулера, эта книга представлена ​​на всех уровнях опыта, поэтому я рекомендую всем.

7 голосов
/ 08 июня 2010

Чтобы лучше понять принципы ТВЕРДОГО, вы должны понять проблему, которую они решают:

Объектно-ориентированное программирование выросло из структурированного / процедурного программирования - оно добавило новую организационную систему (классы и др.), А также модели поведения (полиморфизм, наследование, композиция). Это означало, что ОО не был отделен от структурированного / процедурного, но был прогрессом, и разработчики могли делать очень процедурное ОО, если они хотели.

Итак ... SOLID стал лакмусовой бумажкой, чтобы ответить на вопрос "Я действительно делаю ОО или я просто использую процедурные объекты?" Пять принципов, если следовать им, означают, что вы довольно далеко от ОО-стороны спектра. Несоблюдение этих правил не означает, что вы не выполняете OO, но это означает, что это намного более структурный / процедурный OO.

5 голосов
/ 09 июня 2010

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

Аспектно-ориентированное программирование - это один из подходов, который пытается решить эту проблему. Хорошим примером в C # является сериализация, для которой существует широкий спектр различных атрибутов для различных типов сериализации. Идея заключается в том, что класс не должен реализовывать код, выполняющий сериализацию, а должен объявлять, как он должен быть сериализован. Метаданные - это очень естественное место для включения деталей, которые важны для других подсистем, но не имеют отношения к проверяемой реализации класса.

2 голосов
/ 08 июня 2010

Я думаю, что есть много второстепенных, общих задач, которые класс может выполнить без них, скрывая основную ответственность класса: сериализация, регистрация, обработка исключений, обработка транзакций и т. Д.

Вам решать, какие задачи в вашем классе представляют собой реальную ответственность с точки зрения логики вашего бизнеса / приложения, а что такое просто сантехнический код.

2 голосов
/ 08 июня 2010

Следует помнить о принципах проектирования: всегда есть исключения, и вы не всегда найдете, что ваш сценарий / реализация соответствует заданному принципу на 100%.

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

1 голос
/ 23 ноября 2014

Итак, если вместо разработки одного класса "Dog" с методами "Bark", "Sleep" и "Eat", я должен разработать классы "AnimalWhoBarks", "AnimalWhoSleeps", "AnimalWhoEats" и т. Д.? Зачем? Как это делает мой код лучше? Как мне просто реализовать тот факт, что моя собака не будет спать и будет лаять всю ночь, если она не ела?

«Разделять большие классы на более мелкие» - хороший практический совет, но «каждый объект должен нести единственную ответственность» - абсолютная догма ООП.

Представьте, что .NET Framework был написан с учетом SRP. Вместо 40000 классов у вас будут миллионы.

Обобщенная СРП (здесь важно слово «Обобщенный») - это просто преступление, ИМХО. Вы не можете сократить разработку программного обеспечения до 5 книжных принципов.

0 голосов
/ 07 января 2019

SRP, на мой взгляд, немного расплывчато.Никто не может четко определить, какой должна быть ответственность.То, как я реализую это, заключается в том, что я строго придерживаюсь размера моего метода ниже 40 и нацеливаюсь на значение ниже 15.

Старайтесь следовать здравому смыслу и не зацикливаться на нем.Старайтесь, чтобы классы были ниже 500 строк, а методы - не более 30 строк.Это позволит ему поместиться на одной странице.Как только это станет вашей привычкой, вы заметите, насколько легко масштабировать вашу кодовую базу.

Ссылка: дядя Боб Мартин в Чистом коде

0 голосов
/ 22 мая 2014

S.O.L.I.D означает:

  • Принцип единоличной ответственности
  • Открыто-закрытый принцип
  • Принцип подстановки Лискова
  • Принцип разделения интерфейсов
  • Принцип обращения зависимостей

Это стандарты, на которые мы ссылаемся, когда говорим об ООП. Однако ни один из этих принципов не может быть полностью реализован при разработке программного обеспечения.

Вы можете посмотреть очень хорошо объясняющую презентацию по этой теме здесь http://www.slideshare.net/jonkruger/advanced-objectorientedsolid-principles

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...