Принцип единственной ответственности — The Single Responsibility Principle или SRP — один из пяти основных принципов объектно-ориентированного программирования и проектирования, сформулированных Робертом Мартином.
Принцип декларирует, что каждый объект должен иметь одну обязанность и эта обязанность должна быть полностью инкапсулирована в класс, а все его сервисы должны быть направлены исключительно на обеспечение этой обязанности.
Следование принципу заключается обычно в декомпозиции сложных классов, которые делают сразу много вещей, на простые, отвественность которых очень специализирована. Но также и объединении в отдельный класс однотипной функциональности, которая может оказаться распределённой по многим классам, может рассматриваться как следование этому принципу.
Проектирование классов с направленностью на обеспечение единственной обязанности упрощает дальнейшие модификации и сопровождение, так как проще разобраться в одном блоке функциональности, нежели распутывать сложные взаимосвязи между различными функциональными блоками. Также при модификации логики в одном месте приложения снижаются риски возникновения проблем в других «неожиданных» его местах.
Следование SRP весьма полезная практика с точки зрения повторного использования кода. Сложные объекты с комплексными зависимостями обычно очень сложно использовать повторно, особенно если нужна только часть реализованного в них функционала. А небольшие классы с чётко очерченным функционалом, напротив, проще использовать повторно, так как они не избыточные и редко тянут за собой существенный объём зависимостей.
Наиболее ярким анти‑паттерном, нарушающим принцип единственной ответственности, является использование God‑объектов, которые «слишком много знают» или «слишком много умеют». Возникают такие «божественные объекты» обычно из‑за любви разработчиков к абстракции — если возводить абстракцию в абсолют, то вполне можно любой объект реального мира отразить в приложении в виде экзепляра некого универсального класса. На словах это даже может выглядеть логично, но на практике почти всегда это приводит к проблемам сопровождаемости. Обычно такие объекты становятся центральной частью системы, а их модификация крайне сложна, так как становится очень сложно предсказать, как изенение кода для решения текущей задачи может сказаться на ранее реализованной функциональности.
Но, как и любые другие принципы, SRP требует сознательного и осмысленного применения. Чрезмерная декомпозиция может оказаться и вредной, если она приводит к большей сложности или усложняет сопровождение.
Например, часто используемый во фреймворках паттерн ActiveRecord нарушает принцип единственной ответственности. ActiveRecord реально объединяет в себе очень много функциональных возможностей и часто смешивает бизнес‑логику и работу со слоем хранения. При этом использование ActiveRecord часто является удобным и целесообразным. На этом примере становится ясно, что SRP — это не догма, а нарушение этого принципа вполне может быть логичным и целесообразным.
Принципы SOLID :