В реальной жизни

В реальной жизни SRP также позволяет решать задачи эффективнее. Ниже мы привели несколько примеров из проектов, над которыми работали.

Валидация форм

В вебе одна из распространённых задач — валидация форм.

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

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

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

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

Принцип единственной ответственности позволяет сделать валидацию независимой от формата представления данных

Применение SRP для валидации позволяет:

  • уменьшить код обработчиков форм, выделив валидацию в отдельный модуль;
  • держать валидацию значений в одном месте, собрав всё, что к ней относится в одном модуле;
  • валидировать не только формы, а любые наборы данных, которые соответствуют обговорённому формату валидатора.

Обработка сокет-событий

Для работы с данными в реальном времени в вебе часто используется socket.io.

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

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

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

Настройка бюджета во второй версии Тяжеловато

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

В первой версии бюджет и сумма на день были частями одной сущности — бюджета. Это сильно усложняло расчёты и увеличивало объём обработчиков пользовательских событий.

По принципу единственной ответственности работа с суммой на день и с общим бюджетом на весь период — разные задачи. Причина изменения суммы на день — ввод траты; причина изменения бюджета — изменение настроек бюджета.

«Общий бюджет» (слева) и «Сумма на день» (справа)

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

Это позволило:

  • уменьшить количество эдж-кейсов при расчётах сумм;
  • сделать общение между сущностями более прозрачным;
  • разделить ответственность за обработку трат и настроек.