11

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

A sample Domain Model

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

A sample Service Layer

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

Рассмотрим пример, приведенный на первой диаграмме выше. Существует два «объекта» Contract и Product. Они сохраняются в базе данных с помощью mapper. В этом примере есть 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(). Мой подход дает нам более тонкий контроль, потому что служба имеет знания уровня абстракции базы данных, где, поскольку сущности не должны.

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

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

ответ

1

Модель домена представляет собой объект, а также поведение лучше, чем анемичное. Потому что поведение связано с ним. Основным примером является то, что dog может bark, breathe и eat. На уровне обслуживания модель улучшена с помощью BarkHandler и BreatheHandler.

Подход модели домена основан на шаблоне проектирования UML.My previous answer here. Для подхода к моделированию аномальных доменов (уровень обслуживания) сложно сделать UML-диаграмму (диаграмму классов), и даже если вы смогли ее создать, она официально не принимается, поэтому люди будут иметь другую интерпретацию.

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

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

Но богатая доменная модель does not have the flexibility как anemic domain model есть. Вы не можете добавлять поведение к модели, не меняя класс модели домена, если вы не используете наследование. В то время как в модели анемичного домена вы можете даже поменять его на уровне времени выполнения.

6

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

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

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

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

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

Таким образом, преимущества использования подхода «Модель домена» - четкое разделение проблем и повышенная проверяемость.

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

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

Domain Driven Design and Development In Practice - An interesting article on DDD

Dependency Injection, Design patterns using Spring and Guice - Great book on dependency injection

С уважением,

Emanuel Луис Lariguet Бельтраме

 Смежные вопросы

  • Нет связанных вопросов^_^