Thursday, September 11, 2008

Сервисы в Domain-Driven дизайне.

В предметной области (домене) встречаются операции, которые не являются частью сущностей (Entity) или простых объектов-значений (Value Objects). Некоторые из них, по сути, представляют некоторое действие или деятельность, но следуя парадигме Domain Driven Design (DDD), где все является объектами, эти действия необходимо представить как объекты. Распространенной ошибкой является вынесение логики (поведения) из сущностей и объектов-значений, и помещение ее в классы сервисов. Сложные операции, в итоге, переполняют объект, искажая его первоначальную роль, поэтому операция в сервисе должна объединять и координировать логику из других доменных объектов, связывая объекты таким образом, что бы представляемые ими концепции, могли рассматриваться отдельно. В отличие от сущностей и объектов-значений сервисы объявлены в терминах того, что они могут сделать для клиента. Имена сервисов строятся на основании деятельности, которую они представляют, в отличие от сущностей.

Основными характеристиками хорошего сервиса являются:

  • операции сервиса принадлежат концепции домена (предметной области), но не являются частью сущности или объекта-значения;
  • интерфейс определяется в терминах других элементов домена (предметной области);
  • сервис не хранит состояние (stateless).

Примеры сервисов домена: IOrderProcessor, IProductFinder, IFundsTransferService.

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

  • cервисы приложения(Application);
  • сервисы предметной область(Domain);
  • инфраструктурные сервисы(Infrastructure).

Инфраструктурные сервисы, это что взаимодействует непосредственно с внешними ресурсами, например файловой системой, базой данных, реестром, сетью и т.п. Примером инфраструктурного сервиса может служить: IEmailSender.

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

Рассмотрим пример разбиения сервисов по слоям:


Application:
Funds Transfer App Service
- обрабатывает входные данные (например запрос в формате XML);
- обращается к сервису домена для осуществления перевода;
- ждет подтверждения;
- решает посылать ли нотификацию через инфраструктурный сервис.

Domain:
Funds Transfer Domain Service
- взаимодействует с необходимыми объектами Account и Ledger, вызывая соответствующую логику предметной области(домена);
- предоставляет результат (разрешен ли перевод или нет и т.п.).

Infrastructure:
Send Notification Service
- посылает e-mail'ы, факсы и осуществляет другую нотификацию поддерживаемую приложением.

Литература: "Domain-Driven Design: Tackling Complexity in the Heart of Software" by Eric Evans.

No comments:

Post a Comment