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

Материал из Википедии — свободной энциклопедии
(перенаправлено с «Принцип единственной обязанности»)
Перейти к: навигация, поиск
Классу позволительно слишком много. Вероятнее всего при внесении в его код изменений, возникнут трудности. Причиной тому станет нарушение SRP.

В ООП принцип единственной ответственности (англ. The Single Responsibility Principle, SRP) обозначает, что каждый объект должен иметь одну ответственность и эта ответственность должна быть полностью инкапсулирована в класс. Все его поведения должны быть направлены исключительно на обеспечение этой ответственности.

« A class should have only one reason to change.
Robert C. Martin
»

Описание[править | править вики-текст]

Термин SRP был введён Робертом С. Мартином в одноименной статье как часть SOLID, ставших популярными благодаря его книге "Быстрая разработка программ. Принципы, примеры, практика." [1]. Мартин описал SRP, основываясь на закономерности, описанной Томом ДеМарко[2] и Мейлиром Пейдж-Джонсом[3] и названной связностью.

В SOLID — буква «S» является аббревиатурой, которая образована сокращением от английского названия принципа единственной ответственности.

Мартин определяет ответственность как причину изменения и заключает, что классы должны иметь одну и только одну причину для изменений. Например, представьте себе класс, который составляет и печатает отчёт. Такой класс может измениться по двум причинам:

  1. может измениться само содержимое отчёта
  2. может измениться формат отчёта.

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

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

Использование[править | править вики-текст]

Возникает вопрос, когда стоит использовать этот принцип? Всё же принцип - это не закон и SRP стоит применять в зависимости от того, как изменяется приложение:

  • если при изменении кода, отвечающего за одну ответственность, в приложении появляются исправления кода, отвечающего за другую ответственность, то это первый сигнал о нарушении SRP.
  • если же изменения кода, отвечающего за одну ответственность, не вносят изменения в код, отвечающий за другую ответственность, то этот принцип можно не применять.
Пример класса, который подаёт признаки нарушении SRP принципа.

Слепое следование принципу единственной ответственности приводит к избыточной сложности приложения, его поддержки и тестированию. SRP стоит применять только тогда, когда это оправдано. Например, приложение, в котором используется ActiveRecord - паттерн, который позволяет легко связать данные объектов и данные из базы данных. При ActiveRecord много ответственностей сконцентрировано в одном месте и поэтому можно утверждать, что ActiveRecord нарушает SRP и тем самым становится антипаттерном.[4] Принцип SRP можно применить только в том случае, когда:

  • объекту класса становится позволительно слишком много;
  • доменная логика концентрируется только в одном классе;
  • любое изменение логики поведения объекта приводит к изменениям в других местах приложения, где это не подразумевалось изначально;
  • приходится тестировать, исправлять ошибки, компилировать различные места приложения, даже если за их работоспособность отвечает третья сторона;
  • невозможно легко отделить и применить класс в другой сфере приложения, так как это потянет ненужные зависимости.
Вроде классы разделены по назначениям, но у Response есть признак нарушения SRP. Он зависим от Report. Изменяя Report, например, удалив метод получения заголовка, потребуются внести изменения в Response. А ведь изначально не подразумевалось изменять код формата отчёта. Код проекта не готов к быстрым и безболезненным изменениям.

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

Приёмы соблюдения принципа[править | править вики-текст]

Следующие приёмы позволяют соблюдать принцип единственной ответственности:

Классическим примером[5] нарушения SRP может служить ситуация, когда системе с бизнес-правилами (BRMS) нужно иметь дело с постоянным хранилищем (Persistence[en]). На первых этапах проектирования таких систем создаётся класс, который обрабатывает бизнес правила и содержит логику работы с базой данных. С нарушением SRP появляются признаки плохого проекта, такие как:

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

Если бы система изначально разрабатывалась через тестирование(TDD), то этой проблемы могло бы и не возникнуть. Опираясь на тесты, разработчики могут быстрее представить, какая функциональность необходима пользователю. Таким образом, детали класса появляются задолго до окончательной реализации решения, тем самым влияя на дизайн разрабатываемой системы. Но бывает и так, что разработка через тестирование не приводит к применению шаблона «Выделение класса», тогда к системе применяется рефакторинг с применением шаблонов «Фасад», DAO или «Proxy».

SRP предлагает разделять универсальные классы на конкретные, что сделает их простыми и лёгкими в обслуживании. Подобную идею также выдвигает принцип KISS.[6]

См. также[править | править вики-текст]

Примечание[править | править вики-текст]

  1. Мартин, Роберт. Быстрая разработка программ. Принципы, примеры, практика. — Вильямс, 2004. — ISBN 5845905583.
  2. Tom DeMarco. Structured Analysis and System Specification. — 1 edition. — Prentice Hall, May 21, 1979. — С. 310. — 348 с. — ISBN 0138543801.
  3. Meilir Page-Jones. Practical Guide to Structured Systems Design. — 2 edition. — Prentice Hall, May 14, 1988. — С. 82. — 368 с. — ISBN 8120314824.
  4. Pablo's SOLID Software Development.
  5. ArticleS.UncleBob.PrinciplesOfOod. butunclebob.com. Проверено 5 ноября 2016.
  6. Shivprasad koirala. SOLID architecture principles using simple C# examples - CodeProject. www.codeproject.com. Проверено 6 ноября 2016.

Литература[править | править вики-текст]

  • Robert C. Martin. Clean Code: A Handbook of Agile Software Craftsmanship. — Pearson Education, 2008. — ISBN 978-0-13-608325-2.

Ссылки[править | править вики-текст]