Как вы определяете единую ответственность? - PullRequest
36 голосов
/ 29 октября 2008

Я знаю о "классе, имеющем единственную причину для изменения". Теперь, что это такое? Есть ли какие-то запахи / признаки, которые могли бы сказать, что у класса нет единой ответственности? Или реальный ответ может скрываться в YAGNI и отражать единственную ответственность при первом изменении класса?

Ответы [ 13 ]

24 голосов
/ 29 октября 2008

Принцип единой ответственности

Есть много очевидных случаев, например, CoffeeAndSoupFactory. Кофе и суп в одном приборе могут привести к довольно неприятным результатам. В этом примере устройство может быть разбито на HotWaterGenerator и какое-то Stirrer. Затем из этих компонентов могут быть изготовлены новые CoffeeFactory и SoupFactory, и можно избежать случайного смешивания.

Среди более тонких случаев очень распространено напряжение между объектами доступа к данным (DAO) и объектами передачи данных (DTO). DAO взаимодействуют с базой данных, DTO сериализуются для передачи между процессами и машинами. Обычно DAO требуется ссылка на структуру вашей базы данных, поэтому они не могут использоваться на ваших полнофункциональных клиентах, которые не имеют ни драйверов установленной базы данных, ни необходимых привилегий для доступа к БД.

Запахи кода

  • Методы в классе начинают группироваться по областям функциональности («это методы Coffee и методы Soup»).

  • Реализация многих интерфейсов.

24 голосов
/ 25 ноября 2008

Напишите краткое, но точное описание того, что делает класс.

Если в описании есть слово «и», то его нужно разделить.

11 голосов
/ 29 октября 2008

Ну, этот принцип нужно использовать с солью ... чтобы избежать взрыва класса.

Одна ответственность не распространяется на классы с одним методом. Это означает единственную причину существования ... услугу, которую объект предоставляет своим клиентам.

Хороший способ остаться на дороге ... Используйте объект как метафору человека ... Если бы объект был человеком, кого бы я попросил сделать это? Назначьте эту ответственность соответствующему классу. Однако вы бы не попросили одного и того же человека управлять файлами, вычислять зарплату, выплачивать чеки и проверять финансовые записи ... Почему вы хотите, чтобы один объект выполнял все это? ( все в порядке, если класс берет на себя несколько обязанностей, если они все связаны и согласованы. )

  • Если вы используете CRC-карту, это хороший тонкий совет. Если у вас возникли проблемы с выполнением всех обязанностей этого объекта на карте CRC, возможно, он выполняет слишком много ... максимум 7 может быть хорошим маркером.
  • Еще один запах кода из книги по рефакторингу - это ОГРОМНЫЕ классы. Операция с дробовиком была бы другой ... внесение изменений в одну область в классе приводит к ошибкам в несвязанных областях одного и того же класса ...
  • Обнаружение того, что вы снова и снова вносите изменения в один и тот же класс для несвязанных исправлений ошибок, является еще одним свидетельством того, что класс делает слишком много.
9 голосов
/ 29 октября 2008

Простой и практичный метод проверки единой ответственности (не только классы, но и метод классов) - выбор имени. Когда вы разрабатываете класс, если вы легко находите имя для класса, которое точно определяет, что он определяет, вы на правильном пути. Трудно выбрать имя - это почти всегда признак плохого дизайна.

5 голосов
/ 29 октября 2008

Очевидный признак - когда ваш класс в конечном итоге выглядит как Большой шарик грязи , что на самом деле является противоположностью SRP (принцип единой ответственности).

По сути, все сервисы объекта должны быть направлены на выполнение одной ответственности, то есть каждый раз, когда ваш класс меняется, и добавьте сервис, который не уважает этого, вы знаете, что «отклоняетесь» от «правильного» пути; )

Причина обычно заключается в том, что в класс поспешно добавлены быстрые исправления для исправления некоторых дефектов. Так что причина, по которой вы меняете класс , обычно является наилучшим критерием, чтобы определить, собираетесь ли вы нарушить SRP.

5 голосов
/ 29 октября 2008

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

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

2 голосов
/ 24 декабря 2010

Я также пытался осмыслить ТВЕРДЫЕ принципы OOD , в частности принцип единой ответственности, иначе SRP (как примечание подкаст с Джеффом Этвудом, Джоэлем Спольски и "Дядя Боб" стоит слушать). Большой вопрос для меня: какие проблемы решает SOLID?

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

Полагаю, вы должны спросить себя: какую проблему пытается решить ваш класс? Поднялась ли важная информация, необходимая для решения этой проблемы, на поверхность? Незначительные детали спрятаны так, что вам нужно думать о них только тогда, когда это абсолютно необходимо?

Размышление об этих вещах приводит к программам, которые легче понять, поддерживать и расширять. Я думаю, что это лежит в основе принципов OOD и SOLID, включая SRP.

2 голосов
/ 30 декабря 2009

Мартина Agile Принципы, Шаблоны и Практики в C # очень помогли мне понять SRP. Он определяет SRP как:

У класса должна быть только одна причина для изменения.

Так что же такое изменение вождения?

Мартин ответил:

[...] каждая ответственность - это ось перемен. (стр. 116 )

и далее:

В контексте ПСП мы определяем ответственность как причину изменений. Если вы можете придумать более одного мотива для изменения класса, этот класс несет более одной ответственности (стр. 117 )

На самом деле SRP инкапсулирует изменения. Если изменение произойдет, оно должно оказать локальное воздействие.

Где ЯГНИ?

YAGNI можно красиво комбинировать с SRP: когда вы применяете YAGNI, вы ждете, пока не произойдут какие-то изменения. Если это произойдет, вы сможете четко увидеть обязанности, которые вытекают из причины (ей) изменения.

Это также означает, что обязанности могут развиваться с каждым новым требованием и изменением. Дальнейшие размышления SRP и YAGNI предоставят вам возможность мыслить гибкими проектами и архитектурами.

2 голосов
/ 30 августа 2009

Вот некоторые вещи, которые помогают мне понять, нарушает ли мой класс SRP:

  • Заполните комментарии к документу XML для класса. Если вы используете такие слова, как if, и, но, за исключением случаев, когда и т. Д., Ваши классы, вероятно, делают слишком много.
  • Если ваш класс является доменной службой, в нем должен быть глагол. Часто у вас есть такие классы, как «OrderService», который, вероятно, следует разбить на «GetOrderService», «SaveOrderService», «SubmitOrderService» и т. Д.
2 голосов
/ 25 ноября 2008

Если вы получите MethodA, который использует MemberA и MethodB, который использует MemberB, и это не часть какой-либо схемы параллелизма или управления версиями, вы можете нарушать SRP. 1007 *

Если вы заметили, что у вас есть класс, который просто делегирует вызовы многим другим классам, вы можете оказаться в аду прокси-класса. Это особенно верно, если вы в конечном итоге создаете экземпляр прокси-класса везде, где вы можете просто использовать конкретные классы напрямую. Я видел много этого. Подумайте ProgramNameBL и ProgramNameDAL классы в качестве замены для использования шаблона репозитория.

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