Доменная модель и шаблоны сервисного уровня в P EAA

В статье "Шаблоны архитектуры корпоративных приложений" Мартин Фаулер рассказывает о двух шаблонах организации логики домена: модель домена и уровень обслуживания. Шаблон "Модель предметной области" - это "чистый ООП" подход, при котором модели (те объекты, которые, вероятно, ищутся из базы данных с использованием ORM) содержат бизнес-логику (хотя, вероятно, делегируют ее только логике в другом классе).

Пример модели предметной области

Шаблон Service Layer похож на шаблон Domain Model, но перед ним расположен тонкий слой, содержащий бизнес-операции, которые можно выполнить. В MVC контроллер в основном взаимодействует с сервисным уровнем. Я считаю, что большинство хорошо разработанных веб-приложений MVC используют этот шаблон.

Образец сервисного уровня

Теперь на мой вопрос. Мартин полагает, что подход "Модель предметной области" является более объектно-ориентированным и поэтому лучше. По моему опыту, это очень трудно (см.: невозможно) реализовать на практике.

Возьмите пример, приведенный на первой диаграмме выше. Есть две "сущности" Contract а также Product, Они сохраняются в базе данных с картографом. В примере есть RecognitionStrategy, Мартин помещает методы делегирования в эту стратегию, которая содержит актуальную бизнес-логику, в самих сущностях; клиент выполняет этот расчет с contract.calculateRecognitions или же contract.recognizedRevenue(someDate), При реализации подобных проектов я обычно пишу клиентский интерфейс как strategy.calculateRecognitions(contract) а также strategy.recognizedRevenue(contract, someDate), Это делает уровень обслуживания необходимым для координации стратегии и контракта. Конкретная стратегия используется в сервисе.

Подход Мартина определенно более привлекателен с точки зрения дизайна, но обойти настройку гораздо сложнее:

  1. Передача в стратегии при создании Product это боль. Вам нужно создать Product Через фабрику с конкретным сервисом, который, в свою очередь, передаст его в сущность при его создании.
  2. Менее детальный контроль над доступом к базе данных. В зависимости от настроек ORM, Contract делегирование Product может выполнить запрос в Product, Жадная загрузка Product s в маппере (или ORM) может быть чрезмерно усердным, когда мы загружаем Contract но не собираюсь звонить contract.calculateRecognitions(), Мой подход дает нам более детальный контроль, потому что служба знает уровень абстракции базы данных, а объекты не должны.

Я уверен, что на практике есть больше болевых точек, которые я не перечислил здесь.

Какие конкретные преимущества есть в подходе Мартина, который может убедить меня использовать шаблон чистой модели данных?

2 ответа

Что касается вашего первого замечания, вы должны использовать внедрение зависимостей при создании экземпляра объекта Product. Построение графов объектов является полностью помеченной ответственностью и не должно смешиваться с вашей бизнес-логикой (принцип единой ответственности).

Что касается второго пункта, особенности вашего поставщика должны быть скрыты за уровнем доступа к данным, а ваш DAO или репозиторий должны возвращать объекты в соответствии с вашими потребностями.

Альтернативой для вашего беспокойства по поводу жадной загрузки Продукта (в ситуации, когда отношение является одним ко многим) является добавление Продукта DAO в объект Контракта. При таком подходе вы можете получить Привязку Продукта к контракту, когда это необходимо (возможно, для получения, который также может быть использован внутри компании).

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

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

Таким образом, преимущества использования подхода Domain Model заключаются в четком разделении проблем и повышении тестируемости.

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

Некоторые дополнительные ссылки вы можете найти интересным

Доменное проектирование и разработка на практике - интересная статья о DDD

Внедрение зависимостей, разработка шаблонов с использованием Spring и Guice - отличная книга о внедрении зависимостей

С Уважением,

Эмануэль Луис Ларигет Бельтраме

Доменная модель представляет объект так же, как и его поведение лучше, чем анемичный. Потому что поведение привязано к нему. Базовый пример dog Можно bark, breathe а также eat, В слое Service модель улучшена BarkHandler а также BreatheHandler,

Подход модели предметной области изначально поддерживается шаблоном проектирования UML. Мой предыдущий ответ здесь. Для подхода с анемичной моделью предметной области (сервисный уровень) сложно создать диаграмму UML (диаграмму классов), и даже если вам удалось ее создать, она официально не принята, поэтому у людей будет другая интерпретация.

С точки зрения дизайна, уровень сервиса тоже "independent"или разделены. Рассматривая модель анемичной области class, вы не можете найти поведение (например, сохранить), связанное с моделью домена. Вам нужно искать весь проект, чтобы найти конкретное поведение для модели предметной области. Находясь в богатой доменной модели, вы знаете следы поведения внутри самой доменной модели.

Богатая модель домена имеет лучший модификатор доступа (открытый, закрытый, защищенный) для своих свойств. Как и видимость недвижимости. Например, если вы хотите изменить статус после отправки, вы можете заставить свойство получить доступ к public, но установлен доступ к protected, На уровне сервиса вам нужно сделать доступ к publicили обмануть internal protected и сделать отправитель напрямую изменить свойство с помощью internal access, Но это дополнительная сложность.

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

Другие вопросы по тегам