На это нет однозначного ответа. Хотя вопрос узкий, объяснения нет.
Для меня это что-то вроде бритвы Оккама, если хотите. Это идеал, в котором я пытаюсь измерить свой текущий код. Трудно прибить это простыми и понятными словами. Другой метафорой будет «одна тема», которая столь же абстрактна, то есть трудна для понимания, как «единая ответственность». Третий дескрипт будет «иметь дело с одним уровнем абстракции».
Что это значит практически?
В последнее время я использую стиль кодирования, который состоит в основном из двух фаз:
Фаза I лучше всего описана как творческий хаос. На этом этапе я записываю код, потому что мысли текут - то есть сыры и безобразны.
Фаза II - полная противоположность. Это похоже на уборку после урагана. Это требует наибольшей работы и дисциплины. А потом я смотрю на код с точки зрения дизайнера.
Сейчас я работаю в основном на Python, что позволяет мне думать об объектах и классах позже. Первая фаза I - я пишу только функции и выкладываю их почти случайно в разных модулях. На втором этапе , после того, как я приступил к работе, я более подробно рассмотрю, какой модуль имеет дело с какой частью решения. И пока я просматриваю модули, темы меняются. Некоторые функции тематически связаны. Это хорошие кандидаты на занятия . И после того, как я превратил функции в классы - что почти сделано с отступом и добавлением self
в список параметров в python;) - я использую SRP
как Razor Оккама, чтобы выделить функциональность для других модулей и классов.
Текущий пример может писать небольшую функциональность экспорта на днях.
Была необходимость в CSV , Excel и комбинированных листах Excel в формате ZIP.
Простая функциональность была выполнена в трех видах (= функции). Каждая функция использовала общий метод определения фильтров и второй метод для извлечения данных. Затем в каждой функции выполнялась подготовка экспорта, которая доставлялась в виде ответа от сервера.
Было перепутано слишком много уровней абстракции:
I) работа с входящим / исходящим запросом / ответом
II) определение фильтров
III) получение данных
IV) преобразование данных
Легким шагом было использование одной абстракции ( exporter
) для работы со слоями II-IV на первом этапе.
Осталась только тема, касающаяся запросов / ответов . На том же уровне абстракции извлекает параметры запроса, что нормально. Так что я имел за это мнение одну «ответственность».
Во-вторых, мне пришлось разбить экспортер, который, как мы видели, состоял как минимум из трех других уровней абстракции.
Определение критериев фильтра и фактическое извлечение почти на одном уровне абстракции (фильтры необходимы для получения правильного подмножества данных). Эти уровни были помещены в нечто вроде уровня доступа к данным .
На следующем шаге я разделил действительные механизмы экспорта: там, где требовалась запись во временный файл, я разбил это на две «обязанности»: одну для фактической записи данных на диск и другую часть, которая касалась фактического формата.
По мере формирования классов и модулей все стало яснее, что и где принадлежало. И всегда скрытый вопрос, делает ли класс слишком много .
Как вы определяете, какие обязанности должен иметь каждый класс, и как вы определяете ответственность в контексте ПСП?
Трудно дать рецепт для подражания. Конечно, я мог бы повторить загадочный «один уровень абстракции» - правило, если это помогает.
В основном для меня это своего рода «художественная интуиция», которая ведет к текущему дизайну; Я моделирую код, как художник, который лепит глину или рисует.
Представь меня кодирующим Бобом Россом ;)