В шаблонах архитектуры корпоративных приложений Мартин Фаулер рассказывает о двух шаблонах для организации логики домена: Domain Model и Service Layer. Шаблон модели домена - это подход «чистого ООП», где модели (те объекты, которые, вероятно, просматриваются из базы данных с использованием ORM) содержат бизнес-логику (хотя, вероятно, только делегирование логики в другом классе).Шаблоны модели домена и обслуживания в P EAA
Служба Слой шаблон подобен шаблону домена модели, но с тонким слоем перед ним, содержащий бизнес-операций, которые могут быть выполнены. В MVC контроллер будет в основном взаимодействовать с уровнем обслуживания. Я считаю, что большинство хорошо продуманных веб-приложений MVC используют этот шаблон.
Теперь, на мой вопрос. Мартин предполагает, что подход «Модель домена» является более объектно-ориентированным подходом и поэтому лучше. По моему опыту, на практике это очень сложно (см.: Невозможно).
Рассмотрим пример, приведенный на первой диаграмме выше. Существует два «объекта» Contract
и Product
. Они сохраняются в базе данных с помощью mapper. В этом примере есть RecognitionStrategy
. Мартин ставит методы делегирования этой стратегии, которая содержит фактическую бизнес-логику, в самих сущностях; клиент выполняет этот расчет с contract.calculateRecognitions
или contract.recognizedRevenue(someDate)
. При реализации подобных проектов я обычно пишу клиентский интерфейс как strategy.calculateRecognitions(contract)
и strategy.recognizedRevenue(contract, someDate)
. Это делает уровень обслуживания необходимым для координации стратегии и контракта. Используемая конкретная стратегия вводится в службу.
подход Мартина, безусловно, более привлекательным с точки зрения дизайна, но работа по установке гораздо сложнее:
- Переходя в стратегии, когда инстанцировании
Product
боль. Вам нужно создатьProduct
с помощью фабрики, используемой с использованием конкретной услуги, которая, в свою очередь, передаст ее в сущность при ее создании. - Менее мелкозернистый контроль доступа к базе данных. В зависимости от настроек ORM, делегирование
Contract
наProduct
может выполнять запрос заProduct
. Жесткая загрузкаProduct
s в картографе (или ORM) может быть чрезмерной, когда мы загружаемContract
, но не намереваемся называтьcontract.calculateRecognitions()
. Мой подход дает нам более тонкий контроль, потому что служба имеет знания уровня абстракции базы данных, где, поскольку сущности не должны.
Я уверен, что на практике больше болевых точек, которые я не перечислял здесь.
Какие конкретные преимущества существуют в подходах Мартина, которые могут убедить меня использовать чистую модель модели данных?