что такое сингл респонсибилити

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

Принцип единственной ответственности — The Single Responsibility Principle или SRP — один из пяти основных принципов объектно-ориентированного программирования и проектирования, сформулированных Робертом Мартином.

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

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

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

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

Наиболее ярким анти-паттерном, нарушающим принцип единственной ответственности, является использование God-объектов, которые «слишком много знают» или «слишком много умеют». Возникают такие «божественные объекты» обычно из-за любви разработчиков к абстракции — если возводить абстракцию в абсолют, то вполне можно любой объект реального мира отразить в приложении в виде экзепляра некого универсального класса. На словах это даже может выглядеть логично, но на практике почти всегда это приводит к проблемам сопровождаемости. Обычно такие объекты становятся центральной частью системы, а их модификация крайне сложна, так как становится очень сложно предсказать, как изенение кода для решения текущей задачи может сказаться на ранее реализованной функциональности.

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

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

Источник

Single Responsibility Principle. Не такой простой, как кажется

что такое сингл респонсибилити. Смотреть фото что такое сингл респонсибилити. Смотреть картинку что такое сингл респонсибилити. Картинка про что такое сингл респонсибилити. Фото что такое сингл респонсибилитиSingle responsibility principle, он же принцип единой ответственности,
он же принцип единой изменчивости — крайне скользкий для понимания парень и столь нервозный вопрос на собеседовании программиста.

Первое серьезное знакомство с этим принципом состоялось для меня в начале первого курса, когда молодых и зеленых нас вывезли в лес, чтобы сделать из личинок студентов — студентов настоящих.

В лесу нас разделили на группы по 8-9 человек в каждой и устроили соревнование — какая группа быстрее выпьет бутылку водки при условии, что первый человек из группы наливает водку в стакан, второй выпивает, а третий закусывает. Выполнивший свою операцию юнит встает в конец очереди группы.

Случай, когда размер очереди был кратен трем, и являлся хорошей реализацией SRP.

Определение 1. Единая ответственность.

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

Рассмотрим объект «Выпивоха» (Tippler).
Для выполнения принципа SRP разделим обязанности на троих:

Каждый из участников процесса ответственен за одну компоненту процесса, то есть имеет одну атомарную ответственность — выпить, налить или закусить.

Выпивоха же, в свою очередь является фасадом для данных операций:

что такое сингл респонсибилити. Смотреть фото что такое сингл респонсибилити. Смотреть картинку что такое сингл респонсибилити. Картинка про что такое сингл респонсибилити. Фото что такое сингл респонсибилити

Зачем?

Человек-программист пишет код для человека-обезьяны, а человек-обезьяна невнимателен, глуп и вечно куда-то спешит. Он может удержать и понять около 3 — 7 термов в один момент времени.
В случае выпивохи этих термов три. Однако если мы напишем код одной простыней, то в нем появятся руки, стаканы, мордобои и бесконечные споры о политике. И все это будет в теле одного метода. Уверен — вы видели такой код в своей практике. Не самое гуманное испытание для психики.

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

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

Так вот, SRP — это принцип, объясняющий КАК декомпозировать, то есть где провести линию разделения.

Он говорит, что декомпозировать надо по принципу разделения «ответственности», то есть по задачам тех или иных объектов.

что такое сингл респонсибилити. Смотреть фото что такое сингл респонсибилити. Смотреть картинку что такое сингл респонсибилити. Картинка про что такое сингл респонсибилити. Фото что такое сингл респонсибилити

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

(Ой, кажется это уже OCP принцип, и я нарушил ответственность этого поста)

И, конечно же, минусы:

Определение 2. Единая изменчивость.

Позвольте господа! Класс выпивохи же также выполняет единую ответственность — он выпивает! И вообще, слово «ответственность» — понятие крайне размытое. Кто-то ответственен за судьбу человечества, а кто-то ответственен за поднимание опрокинутых на полюсе пингвинов.

Рассмотрим две реализации выпивохи. Первая, указанная выше, содержит в себе три класса — налить, выпить и закусить.

Вторая, написана через методологию «Вперед и только вперед» и содержит всю логику в методе Act:

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

Тогда мы лезем в интернет и узнаем другое определение SRP — Принцип единой изменчивости (Single Changeability Principle).

SCP гласит, что «У модуля есть один и только один повод для изменения«. То есть «Ответственность — это повод для изменения».

(Похоже, ребята, придумавшие изначальное определение были уверены в телепатических способностях человека-обезьяны)

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

Определение 3. Локализация изменений.

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

Начнем логировку с процесса наливания:

Инкапсулировав ее в PourOperation, мы поступили мудро с точки зрения ответственности и инкапсуляции, но вот с принципом изменчивости у нас теперь конфуз. Помимо самой операции, которая может меняться, изменчивой становится и сама логировка. Придется разделять и делать специальный логировщик для операции наливания:

Дотошный читатель заметит, что LogAfter, LogBefore и OnError также могут меняться по отдельности, и по аналогии с предыдущими действиями создаст три класса: PourLoggerBefore, PourLoggerAfter и PourErrorLogger.

А вспомнив, что операций для выпивохи три — получаем девять классов логирования. В итоге весь выпивоха состоит из 14 (. ) классов.

Гипербола? Едва ли! Человек-обезьянка с декомпозиционной гранатой раздробит “наливателя” на графин, стакан, операторы наливания, сервис подачи воды, физическую модель столкновения молекул и следующий квартал будет пытаться распутать зависимости без глобальных переменных. И поверьте — он не остановится.

Именно на этом моменте многие приходят к выводу, что SRP — это сказки из розовых королевств, и уходят вить лапшу.

… так и не узнав о существовании третьего определения Srp:

«Принцип единой ответственности гласит, что схожие для изменения вещи должны храниться в одном месте«. или “То, что изменяется вместе, должно храниться в одном месте

То есть, если мы меняем логировку операции, то мы должны это менять в одном месте.

Это очень важный момент — так как все объяснения SRP, которые были выше, говорили о том, что надо дробить типы, пока они дробятся, то есть накладывало «ограничение сверху» на размер объекта, а теперь мы говорим уже и об «ограничении снизу». Иными словами, SRP не только требует «дробить пока дробится», но и не перестараться — «не раздробить сцепленные вещи». Это великая битва бритвы Оккама с человеком-обезьяной!

что такое сингл респонсибилити. Смотреть фото что такое сингл респонсибилити. Смотреть картинку что такое сингл респонсибилити. Картинка про что такое сингл респонсибилити. Фото что такое сингл респонсибилити

Теперь выпивохе должно стать полегче. Помимо того, что не надо дробить логировщик IPourLogger на три класса, мы также можем объединить все логировщики в один тип:

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

В результате у нас 5 классов для решения задачи выпивания:

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

И было в этом списке еще около 10-ти бизнес операций с жуткой связанностью. Объект счета нужен был почти всем. Идентификатор точки и имя клиента нужны были в половине вызовов.

После часового рефакторинга, мы смогли отделить инфраструктурный код и некоторые нюансы работы с аккаунтом в отдельные методы/классы. God метод полегчал, но осталось 100 строк кода, которые распутываться никак не хотели.

Лишь через несколько дней пришло понимание, что суть этого «полегчавшего» метода — и есть бизнес алгоритм. И что изначальное описание ТЗ было довольно сложным. И именно попытка разбить на куски этот метод будет нарушением SRP, а не наоборот.

Формализм.

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

Формализм 1. Определение SRP

Формализм 2. Необходимые критерии самопроверки.

Мне не встречались достаточные критерии выполнения SRP. Но есть необходимые условия:

1) Задайте себе вопрос — что делает этот класс/метод/модуль/сервис. вы должны ответить на него простым определением. ( благодарю Brightori )

Впрочем иногда подобрать простое определение очень сложно

2) Фикс некоторого бага или добавление новой фичи затрагивает минимальное количество файлов/классов. В идеале — один.

Так как ответственность (за фичу или баг) инкапсулированна в одном файле/классе, то вы точно знаете где искать и что править. Например: фича изменения вывода логировки операций потребует изменить только логировщик. Бегать по всему остальному коду не требуется.

Другой пример — добавление нового UI-контрола, схожего с предыдущими. Если это заставляет вас добавить 10 разных сущностей и 15 разных конвертеров — кажется, вы “передробили”.

Если при добавлении новой операции «Вылить водку под стол» вам нужно затронуть логировщик, операцию выпивания и выливания — то похоже, что ответственности разделены криво. Безусловно, это не всегда возможно, но нужно стараться снизить этот показатель.

4) При уточняющем вопросе про бизнес логику (от разработчика или менеджера) вы лезете строго в один класс/файл и получаете информацию только от туда.

Фичи, правила или алгоритмы компактно написаны каждая в одном месте, а не разбросаны флагами по всему пространству кода.

Наш класс или метод ответственен за что-то одно, и ответственность отражена в его названии

AllManagersManagerService — скорее всего, God-класс
LocalPayment — вероятно, нет

Формализм 3. Методика разработки «Оккама-first».

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

Важно запомнить правило: «ошибаться лучше в большую сторону», или «не уверены — не дробите». Если, например, ваш класс собирает в себе две ответственности — то он по прежнему понятен и его можно распилить на два с минимальным изменением клиентского кода. Собирать же из осколков стекла стакан, как правило, сложнее из-за размазанного по нескольким файлам контекста и отсутствия необходимых зависимостей в клиентском коде.

Пора закругляться

Сфера применения SRP не ограничивается ООП и SOLID. Он применим к методам, функциям, классам, модулям, микросервисам и сервисам. Он применим как к “фигакс-фигакс-и-в-прод”, так и к “рокет-сайнс” разработке, везде делая мир чуточку лучше. Если задуматься, то это едва ли не фундаментальный принцип всей инженерии. Машиностроение, системы управления, да и вообще все сложные системы — строятся из компонентов, и “недодробление” лишает конструкторов гибкости, “передробление” — эффективности, а неверные границы — разума и душевного спокойствия.

что такое сингл респонсибилити. Смотреть фото что такое сингл респонсибилити. Смотреть картинку что такое сингл респонсибилити. Картинка про что такое сингл респонсибилити. Фото что такое сингл респонсибилити

SRP не выдуман природой и не является частью точной науки. Он вылезает из наших с вами биологических и психологических ограничений.Это всего лишь способ контролировать и развивать сложные системы при помощи мозга человека-обезьяны. Он рассказывает нам, как декомпозировать систему. Изначальная формулировка требовала изрядного навыка телепатии, но надеюсь, эта статья слегка развеяла дымовую завесу.

Источник

Добавить комментарий

Ваш адрес email не будет опубликован. Обязательные поля помечены *