Сервисы бывают трех видов: доменные , прикладные и инфраструктурные .
- Доменные сервисы : инкапсулирует
бизнес-логику , которая не вписывается в доменный объект и НЕ является типичной операцией CRUD - они принадлежат репозиторию .
- Службы приложений : используются внешними потребителями для связи с вашей системой (например, веб-службы ). Если потребителям нужен доступ к операциям CRUD, они будут выставлены здесь.
- Инфраструктурные услуги : Используются для выявления технических проблем (например, MSMQ, поставщик электронной почты и т. Д.).
Держать доменные службы вместе с вашими доменными объектами разумно - все они сосредоточены на доменной логике. И да, вы можете внедрить репозитории в свои сервисы.
Службы приложений обычно используют доменные службы и репозитории для обработки внешних запросов.
Надеюсь, это поможет!
(Если вам не хочется читать, внизу есть резюме :-)
Я тоже боролся с точным определением сервисов приложений. Хотя ответ Виджая был очень полезен для моего процесса мышления месяц назад, я пришел к тому, что не согласен с его частью.
Другие источники
Там очень мало информации о сервисах приложений. Такие темы, как совокупные корни, репозитории и доменные сервисы, широко обсуждаются, но сервисы приложений упоминаются лишь кратко или вообще не упоминаются.
В статье MSDN Magazine «Введение в доменно-управляемый дизайн» описываются службы приложений как способ преобразования и / или представления модели вашего домена для внешних клиентов, например, как служба WCF. Так Vijay описывает сервисы приложений. С этой точки зрения сервисы приложений являются интерфейсом для вашего домена .
Статьи Джеффри Палермо об Луковой Архитектуре (часть первая , вторая и третья ) хорошо читаются. Он рассматривает службы приложений как понятия уровня приложения , такие как сеанс пользователя. Хотя это ближе к моему пониманию служб приложений, оно все еще не соответствует моим мыслям по этому вопросу.
Мои мысли
Я начал думать о службах приложений как о зависимостях, предоставляемых приложением . В этом случае приложение может быть настольным приложением или службой WCF.
Домен
Время для примера. Вы начинаете с вашего домена. Здесь реализованы все сущности и любые доменные сервисы, которые не зависят от внешних ресурсов. Любые доменные понятия, которые зависят от внешних ресурсов, определяются интерфейсом. Вот возможный макет решения (название проекта выделено жирным шрифтом):
Product
ИProductFactory
классы были реализованы в базовой сборке. ЭтоIProductRepository
то, что, вероятно, поддерживается базой данных. Реализация этого не относится к области и поэтому определяется интерфейсом.Сейчас мы сосредоточимся на
IExchangeRateService
. Бизнес-логика для этого сервиса реализуется внешним веб-сервисом. Однако его концепция все еще является частью домена и представлена этим интерфейсом.инфраструктура
Реализация внешних зависимостей является частью инфраструктуры приложения:
XEExchangeRateService
реализуетIExchangeRateService
доменный сервис, связываясь с xe.com . Эта реализация может использоваться вашими приложениями, использующими модель вашего домена, включая сборку инфраструктуры.заявка
Обратите внимание, что я еще не упомянул службы приложений. Мы посмотрим на них сейчас. Допустим, мы хотим предоставить
IExchangeRateService
реализацию, которая использует кэш для быстрого поиска. Схема этого класса декоратора может выглядеть следующим образом.Заметьте
ICache
параметр? Эта концепция не является частью нашего домена, поэтому это не служба домена. Это сервис приложений . Это зависимость нашей инфраструктуры, которая может быть предоставлена приложением. Давайте представим приложение, которое демонстрирует это:Все это объединяется в приложении следующим образом:
Резюме
Полное приложение состоит из трех основных слоев:
Доменный уровень содержит доменные объекты и автономные доменные службы. Любые доменные концепции (включая доменные службы, но также и репозитории), которые зависят от внешних ресурсов, определяются интерфейсами.
Уровень инфраструктуры содержит реализацию интерфейсов из уровня домена. Эти реализации могут вводить новые не доменные зависимости, которые должны быть предоставлены приложению. Это сервисы приложений и представлены интерфейсами.
Прикладной уровень содержит реализацию сервисов приложений. Прикладной уровень также может содержать дополнительные реализации доменных интерфейсов, если реализации, предоставляемые инфраструктурным уровнем, недостаточны.
Хотя эта перспектива может не совпадать с общим определением служб DDD, она отделяет домен от приложения и позволяет совместно использовать сборку домена (и инфраструктуры) между несколькими приложениями.
источник
IExchangeRateService
интерфейс? Это концепция домена, то есть то, что включено в повсеместный язык вашего клиента. Другие части вашего домена могут зависеть от этой услуги, поэтому ее интерфейс определен на уровне домена. Но поскольку его реализация включает в себя внешний веб-сервис, реализующий класс находится на уровне инфраструктуры. Таким образом, уровень домена касается только бизнес-логики.ExchangeRate
экземпляром, который содержит базовую валюту, контрвалюту и значение обменного курса между этими двумя валютами. Эти тесно связанные значения представляют концепцию «обменного курса» в домене, поэтому они находятся на уровне домена. Хотя это может показаться простым DTO, в DDD он называется объектом-значением и может содержать дополнительную бизнес-логику для сравнения или преобразования экземпляров.Лучший ресурс, который помог мне понять разницу между службой приложений и службой домена, - это Java-реализация примера груза Эрика Эванса, найденного здесь . Если вы загрузите его, вы можете проверить внутренние компоненты RoutingService (доменная служба) и BookingService, CargoInspectionService (которые являются службами приложений).
Мой 'ага' момент был вызван двумя вещами:
Читая описание Услуг по ссылке выше, точнее это предложение:
Читая этот блог , особенно эту часть:
источник
Доменная служба является расширением домена. Это следует рассматривать только в контексте домена. Это не какое-то действие пользователя, например закрытие аккаунта или что-то в этом роде. Доменная служба подходит там, где нет государства. В противном случае это будет объект домена. Доменная служба делает что-то, что имеет смысл только тогда, когда выполняется с другими участниками (объектами домена или другими службами). И это имеет смысл - ответственность другого слоя.
Сервис приложений - это тот уровень, который инициализирует и контролирует взаимодействие между объектами домена и сервисами. Процесс обычно такой: получить объект (или объекты) домена из хранилища, выполнить действие и поместить его (их) туда (или нет). Он может делать больше - например, он может проверять, существует ли объект домена или нет, и генерировать исключения соответственно. Таким образом, он позволяет пользователю взаимодействовать с приложением (и, вероятно, именно отсюда и происходит его имя) - путем манипулирования объектами и службами домена. Сервисы приложений должны, как правило, представлять все возможные варианты использования, Вероятно, лучшее, что вы можете сделать, прежде чем думать о домене, - это создать интерфейсы сервисов приложений, которые позволят вам лучше понять, что вы действительно пытаетесь сделать. Наличие таких знаний позволяет вам сосредоточиться на домене.
Репозитории, вообще говоря, могут быть внедрены в доменные сервисы, но это довольно редкий сценарий. Это прикладной уровень, который делает это большую часть времени, хотя.
источник
Из Красной книги (Внедрение доменного дизайна, Вон Вернон), вот как я понимаю концепции:
Доменные объекты ( сущности и объекты значений ) инкапсулируют поведение, требуемое (суб) доменом, делая его естественным, выразительным и понятным.
Доменные службы инкапсулируют такое поведение, которое не вписывается в один объект домена. Например, книга библиотека одалживая
Book
кClient
(с соответствующимиInventory
изменениями) , может сделать это от службы домена.Службы приложений обрабатывают поток сценариев использования, включая любые дополнительные проблемы, необходимые в дополнение к домену. Он часто предоставляет такие методы через свой API для использования внешними клиентами. Чтобы опираться на наш предыдущий пример, наша служба приложений может предоставить метод,
LendBookToClient(Guid bookGuid, Guid clientGuid)
который:Client
.Book
.Client
иBook
) для обработки фактической доменной логики предоставления книги клиенту. Например, я полагаю, что подтверждение доступности книги определенно является частью логики предметной области.Служба приложений, как правило, должна иметь очень простой поток. Сложные потоки сервисов приложений часто указывают на то, что логика домена просочилась из домена.
Как можно надеяться, вы можете видеть, что модель предметной области остается очень чистой , и ее легко понять и обсудить с экспертами в предметной области, поскольку она содержит только свои собственные, реальные проблемы бизнеса. Поток приложений , с другой стороны, также намного проще в управлении, поскольку он избавлен от проблем в области, становится лаконичным и простым.
источник
Millett, C (2010). Профессиональные шаблоны проектирования ASP.NET. Wiley Publishing. 92.
источник
Доменные службы . Служба, выражающая бизнес-логику, которая не является частью какого-либо совокупного корня.
У вас есть 2 агрегата:
Product
который содержит имя и цену.Purchase
который содержит дату покупки, список продуктов, заказанных с количеством и ценой продукта на тот момент, и способ оплаты.Checkout
не входит ни в одну из этих двух моделей и является концепцией вашего бизнеса.Checkout
может быть создан как доменная служба, которая выбирает весь продукт и вычисляет общую стоимость, оплачивает сумму, вызывая другую доменную службуPaymentService
с частью реализации инфраструктуры, и преобразует ее вPurchase
.Службы приложений . Служба, которая «координирует» или использует методы домена. Это может быть так просто, как просто ваш контроллер.
Это место, где вы обычно делаете:
Вы можете выполнить валидацию здесь, например, проверить, является ли a
Product
уникальным. ЕслиProduct
уникальное существо не является инвариантом, то оно должно быть частью доменной службы, которая может быть вызвана,UniqueProductChecker
поскольку она не может быть частьюProduct
класса и взаимодействует с несколькими агрегатами.Вот полный пример проекта DDD: https://github.com/VaughnVernon/IDDD_Samples
Вы можете найти множество примеров службы приложений и пару доменных служб
источник
Думайте о доменной службе как об объекте, который реализует бизнес-логику или бизнес-правила, связанные с логикой, на объектах домена, и эту логику трудно вписать в одни и те же доменные объекты, а также она не вызывает изменения состояния доменной службы (доменная служба является объектом без «состояние» или, лучше, без состояния, которое имеет деловое значение), но в конечном итоге изменяет состояние только тех объектов домена, с которыми работает.
В то время как служба приложений реализует логику аппликативного уровня как взаимодействие с пользователем, проверку ввода, логику, не связанную с бизнесом, а с другими проблемами: аутентификацией, безопасностью, отправкой по электронной почте и т. Д., Ограничивая себя простым использованием служб, предоставляемых объектами домена.
Примером этого может быть следующий сценарий, предназначенный только для объяснения цели: мы должны реализовать очень маленькое вспомогательное приложение, которое выполняет простую операцию, то есть «включает свет, когда кто-то открывает дверь комнаты дома, чтобы войти и выключите свет, когда закроете дверь, выходящую из комнаты ".
Упрощая много мы рассмотрим только две сущности домена:
Door
иLamp
каждый из них имеет 2 состояния, respectevelyopen/closed
иon/off
, и методы , характерные для работающих изменений состояния на них.В этом случае нам нужна служба домена, которая выполняет определенную операцию включения света, когда кто-то открывает дверь снаружи, чтобы войти в комнату, потому что объекты двери и лампы не могут реализовать эту логику способом, который мы считаем подходящим к их природе .
Мы можем вызвать нашу доменную службу как
DomoticDomainService
и реализовать 2 метода:OpenTheDoorAndTurnOnTheLight
иCloseTheDoorAndTurnOffTheLight
эти 2 метода соответственно изменяют состояние обоих объектов,Door
а такжеLamp
наopen/on
иclosed/off
.Состояние входа или выхода из комнаты, которого нет в объекте службы домена и в объектах домена, но будет реализовано как простое взаимодействие пользователя с прикладной службой, которую мы можем вызвать
HouseService
, которая реализует некоторые обработчики событий какonOpenRoom1DoorToEnter
иonCloseRoom1DoorToExit
, и так далее, для каждой комнаты (это только пример для объяснения цели ..) , которая соответственно будет касаться методов обслуживания домена вызова для выполнения поведения с участием (мы не рассматривали сущность,Room
потому что это только пример) ,Этот пример, далеко не являющийся хорошо разработанным приложением реального мира, имеет единственную цель (как уже говорилось много раз), чтобы объяснить, что такое Доменная служба и чем она отличается от Службы приложений, надеюсь, что она понятна и полезна.
источник