Проектирование на основе домена: служба домена, служба приложения - PullRequest
228 голосов
/ 15 февраля 2010

Может ли кто-нибудь объяснить разницу между услугами домена и приложения, приведя несколько примеров? И, если служба является службой домена, я бы поместил фактическую реализацию этой службы в сборку домена, и если да, я бы также внедрил репозитории в эту службу домена? Некоторая информация была бы очень полезна.

Ответы [ 7 ]

301 голосов
/ 17 февраля 2010

Услуги бывают трех видов: Доменные службы , Службы приложений и Инфраструктурные услуги .

  • Доменные службы : инкапсулирует бизнес-логика , которая не является естественной вписываются в доменный объект и являются НЕ типичными операциями CRUD - они будут принадлежать репозиторию .
  • Службы приложений : Используется внешние потребители, чтобы поговорить с вашим система (думаю веб-сервисы ). Если потребителям нужен доступ к операциям CRUD, они будут здесь представлены.
  • Инфраструктурные услуги : Используется для абстрактные технические проблемы (например, MSMQ, поставщик электронной почты и т. Д.).

Разумно хранить доменные службы вместе с вашими доменными объектами - все они сосредоточены на доменной логике. И да, вы можете внедрять репозитории в свои сервисы.

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

Надеюсь, это поможет!

103 голосов
/ 10 марта 2011

(Если вам не хочется читать, внизу есть сводка: -)

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

Другие ресурсы

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

В статье MSDN Magazine Введение в доменно-управляемый дизайн описывает службы приложений как способ преобразования и / или представления модели вашего домена для внешних клиентов, например, как сервис WCF. Так Vijay описывает сервисы приложений. С этой точки зрения сервисы приложений представляют собой интерфейс вашего домена .

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

Мои мысли

Я начал думать о службах приложений как о зависимостях, предоставляемых приложением . В этом случае приложение может быть настольным приложением или службой WCF.

Домен

Время для примера. Вы начинаете с вашего домена. Здесь реализованы все сущности и любые доменные сервисы, которые не зависят от внешних ресурсов. Любые доменные понятия, которые зависят от внешних ресурсов, определяются интерфейсом. Вот возможный макет решения (название проекта выделено жирным шрифтом):

My Solution
- <b>My.Product.Core</b> (My.Product.dll)
  - DomainServices
      IExchangeRateService
    Product
    ProductFactory
    IProductRepository

Классы Product и ProductFactory были реализованы в базовой сборке. IProductRepository - это то, что, вероятно, поддерживается базой данных. Реализация этого не относится к области и поэтому определяется интерфейсом.

Пока мы сосредоточимся на IExchangeRateService. Бизнес-логика для этого сервиса реализуется внешним веб-сервисом. Однако его концепция все еще является частью домена и представлена ​​этим интерфейсом.

Инфраструктура

Реализация внешних зависимостей является частью инфраструктуры приложения:

My Solution
+ <b>My.Product.Core</b> (My.Product.dll)
- <b>My.Product.Infrastructure</b> (My.Product.Infrastructure.dll)
  - DomainServices
      XEExchangeRateService
    SqlServerProductRepository

XEExchangeRateService реализует службу домена IExchangeRateService, связываясь с xe.com . Эта реализация может использоваться вашими приложениями, использующими модель вашего домена, включая сборку инфраструктуры.

Применение

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

public class CachingExchangeRateService : IExchangeRateService
{
    private IExchangeRateService service;
    private ICache cache;

    public CachingExchangeRateService(IExchangeRateService service, ICache cache)
    {
        this.service = service;
        this.cache = cache;
    }

    // Implementation that utilizes the provided service and cache.
}

Обратите внимание на параметр ICache? Эта концепция не является частью нашего домена, поэтому это не служба домена. Это служба приложений . Это зависимость нашей инфраструктуры, которая может быть предоставлена ​​приложением. Давайте представим приложение, которое демонстрирует это:

My Solution
- <b>My.Product.Core</b> (My.Product.dll)
  - DomainServices
      IExchangeRateService
    Product
    ProductFactory
    IProductRepository
- <b>My.Product.Infrastructure</b> (My.Product.Infrastructure.dll)
  - ApplicationServices
      ICache
  - DomainServices
      CachingExchangeRateService
      XEExchangeRateService
    SqlServerProductRepository
- <b>My.Product.WcfService</b> (My.Product.WcfService.dll)
  - ApplicationServices
      MemcachedCache
    IMyWcfService.cs
  + MyWcfService.svc
  + Web.config

Все это объединяется в приложении следующим образом:

// Set up all the dependencies and register them in the IoC container.
var service = new XEExchangeRateService();
var cache = new MemcachedCache();
var cachingService = new CachingExchangeRateService(service, cache);

ServiceLocator.For<IExchangeRateService>().Use(cachingService);

Резюме

Полное приложение состоит из трех основных слоев:

  • домен
  • инфраструктура
  • применение

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

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

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

Хотя эта перспектива может не совпадать с общим определением служб DDD, она отделяет домен от приложения и позволяет совместно использовать сборку домена (и инфраструктуры) между несколькими приложениями.

35 голосов
/ 12 августа 2011

Лучший ресурс, который помог мне понять разницу между службой приложений и службой домена, - это Java-реализация примера груза Эрика Эванса, найденного здесь . Если вы загрузите его, вы можете проверить внутренние компоненты RoutingService (доменная служба) и BookingService, CargoInspectionService (которые являются службами приложений).

Мой 'ага' момент был вызван двумя вещами:

  • Читая описание Услуг по ссылке выше, точнее это предложение:

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

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

25 голосов
/ 03 января 2017

Из Красной книги (Реализация доменного дизайна, Вон Вернон), вот как я понимаю концепции:

Объекты домена ( объекты и объекты значений ) инкапсулируют поведение, требуемое (под) доменом, делая его естественным, выразительным и понятным.

Доменные службы инкапсулируют такое поведение, которое не подходит для одного объекта домена. Например, библиотека книг, предоставляющая Book Client (с соответствующими изменениями Inventory), может сделать это из доменной службы.

Службы приложений обрабатывают поток сценариев использования, включая любые дополнительные проблемы, необходимые поверх доменов. Он часто предоставляет такие методы через свой API для использования внешними клиентами. Чтобы использовать наш предыдущий пример, наша служба приложений может предоставить метод LendBookToClient(Guid bookGuid, Guid clientGuid), который:

  • Получает Client.
  • Подтверждает свои разрешения. ( Обратите внимание, как мы избавили нашу модель домена от проблем безопасности / управления пользователями. Такое загрязнение может привести ко многим проблемам. Вместо этого мы выполняем это техническое требование здесь, в нашей службе приложений. )
  • Извлекает Book.
  • Вызывает службу домена (передавая Client и Book) для обработки фактической логики домена предоставления книги клиенту. Например, я предполагаю, что подтверждение доступности книги определенно является частью логики предметной области.

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

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

23 голосов
/ 02 августа 2014

Доменная служба является расширением домена. Это следует рассматривать только в контексте домена. Это не какое-то действие пользователя, например закрыть учетную запись или что-то еще. Доменная служба подходит там, где нет государства. В противном случае это будет объект домена. Доменная служба делает что-то, что имеет смысл только тогда, когда это делается с другими участниками (объектами домена или другими службами). И что имеет смысл - это ответственность другого слоя.

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

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

8 голосов
/ 17 января 2017

Доменные службы: Методы, которые на самом деле не подходят для одного объекта или требуют доступа к хранилищу, содержатся в домене Сервисы. Уровень обслуживания домена также может содержать доменную логику свой собственный и является такой же частью модели предметной области, как сущности и ценность объекты.

Службы приложений: Служба приложений - это тонкий слой, который находится над моделью домена и координирует приложение деятельность. Он не содержит бизнес-логики и не содержит состояние любых субъектов; Тем не менее, он может хранить состояние бизнеса рабочий процесс транзакции. Вы используете службу приложений для предоставления API в модель домена, используя шаблон обмена сообщениями «запрос-ответ».

Millett, C (2010). Профессиональные шаблоны проектирования ASP.NET. Wiley Publishing. 92.

1 голос
/ 01 июня 2019

Доменные службы : служба, выражающая бизнес-логику , которая не является частью какого-либо совокупного корня.

  • У вас есть 2 агрегата:

    • Product, который содержит название и цену.
    • Purchase, который содержит дату покупки, список продуктов, заказанных с количеством и ценой продукта на тот момент, и способ оплаты.
  • Checkout не входит ни в одну из этих двух моделей и является концепцией вашего бизнеса.

  • Checkout можно создать как доменную службу, которая выбирает весь продукт и вычисляет общую стоимость, оплачивает сумму, вызывая другую доменную службу PaymentService с частью реализации инфраструктуры и преобразуя ее в Purchase.

Службы приложений : Служба, которая "организует" или использует доменные методы. Это может быть так же просто, как и ваш контроллер.

Это место, где вы обычно делаете:

public String createProduct(...some attributes) {
  if (productRepo.getByName(name) != null) {
    throw new Exception();
  }

  productId = productRepository.nextIdentity();

  product = new Product(productId, ...some attributes);

  productRepository.save(product);

  return productId.value();
  // or Product itself
  // or just void if you dont care about result
}

public void renameProduct(productId, newName) {
  product = productRepo.getById(productId);

  product.rename(newName);

  productRepo.save(product);
}

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

Вот полный пример проекта DDD: https://github.com/VaughnVernon/IDDD_Samples

Вы можете найти множество примеров службы приложений и пару доменных служб

...