Объектно-ориентированное проектирование
От предметного анализа к проектированию
Заголовок раздела «От предметного анализа к проектированию»Когда предметная область уже описана, нужно распределить состояние, поведение и ответственность между выбранными объектами. Многие предметные понятия естественно имеют жизненный цикл и правила: заказ создаётся, оплачивается, доставляется; заявка подаётся, согласуется, отклоняется или закрывается; документ создаётся, подписывается, публикуется или архивируется.
В идеальном мире в этих этапах участвуют не только разработчики и менеджеры, но и эксперты предметной области. Они могут не знать внутреннего устройства ИС с точки зрения программной архитектуры, но способны указать на полезные и неочевидные моменты: исключения, регламенты, реальные документы, устойчивые термины, состояния объектов и правила переходов.
На раннем этапе важно отличать предметный анализ от технического проектирования. Если мы описываем “заявку”, “исполнителя”, “услугу” и “согласование”, речь идёт о предметной модели. Если появляются “контроллер”, “репозиторий”, “DTO” и “адаптер”, мы уже перешли к технической модели.
Распределение ответственности
Заголовок раздела «Распределение ответственности»Ответственность класса — центральная идея. Класс не должен быть просто контейнером данных, если в предметной области с ним связаны важные правила. Но и перегружать один класс всей логикой процесса нельзя. Если операция затрагивает несколько объектов или внешнюю систему, может понадобиться сервис, координатор или адаптер.
Пример распределения ответственности:
| Элемент | Подходящая ответственность | Неподходящая ответственность |
|---|---|---|
| Заказ | знать свои позиции и статус | отправлять HTTP-запрос в платёжную систему |
| Позиция заказа | хранить товар, количество и цену | управлять всем процессом доставки |
| Сервис оформления | координировать создание заказа | хранить внутреннее состояние заказа вместо объекта |
| Репозиторий | загружать и сохранять заказ | принимать бизнес-решение об отмене |
| Адаптер платежей | изолировать внешний платёжный API | определять правила предметной области |
ОО-проектирование не требует, чтобы каждый объект был “умным” до предела. Важно, чтобы правила не терялись и не размазывались случайно. Если правило принадлежит предметной области, его нужно разместить там, где оно будет понятно и проверяемо. Если действие является координацией сценария, оно может принадлежать сервису приложения. Если действие связано с внешней системой, его лучше изолировать техническим адаптером.
Проверка границ ответственности
Заголовок раздела «Проверка границ ответственности»Ответственность можно проверять через вопрос “кто лучше всего знает данные, необходимые для решения?”. Если объект заказа знает свои позиции и статус, логично разместить часть правил заказа рядом с ним. Если решение требует данных нескольких объектов и внешнего сервиса, это уже кандидат на сервис или координатор. Такой подход помогает избегать как анемичной модели, где все объекты только хранят поля, так и монолитного класса, который делает всё.
В учебной модели достаточно показать принцип распределения ответственности, а не проектировать промышленную архитектуру. Важно, чтобы технические элементы были объяснимы: зачем нужен сервис, почему появился репозиторий, что изолирует адаптер и какие предметные правила сохраняются в модели.
Практические методы получения кандидатов разобраны отдельно в методах выделения классов, а нотация результата описана в технической диаграмме классов.