Вопросы относительно доменного дизайна

После прочтения Эрика Эванса "Домен-управляемый дизайн" у меня есть несколько вопросов. Я искал, но не там, где я мог найти удовлетворительные ответы. Пожалуйста, дайте мне знать, если у кого-то из вас есть четкое понимание вопросов ниже.

Мои опасения

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

  2. Может ли Entity иметь методы, имеющие бизнес-логику, в которой он вызывает сервисы инфраструктуры уровня для отправки электронных писем... журналы и т. Д. (Методы Entity, вызывающие IS Services direclty).

  3. Реализация репозитория и классы Factory будут находиться на уровне Infrastrucure. это правильное утверждение?

  4. Может ли уровень пользовательского интерфейса (контроллера) вызывать методы Repositry напрямую? или мы должны вызвать их из уровня приложений?

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

3 ответа

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

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

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

  4. DDD не определяет, можете ли вы пропустить слои или нет. Позднее в книге Эванс немного говорит о наслоении и называет его "Расслабленное наслоение", когда вы позволяете это, так что я думаю, он просто видит это как один из вариантов. Лично я предпочел бы не пропускать пропуски слоев, потому что это облегчает внедрение некоторого поведения в будущем, если вызовы уже проходят правильные слои.

  1. Лично в моем последнем DDD-проекте я использую Unit Of Work, который проводит сессию NHibernate. UoW вводится в репозитории ctor, давая им единственную ответственность за Add, Remove and Find.

  2. Эванс заявил, что одной из частей головоломки, которая отсутствует в книге DDD, является "События домена". Использование чего-то вроде DomainEvents Уди Даана даст вам полностью отделенную архитектуру (объект домена просто вызывает событие). Лично я использую модифицированную версию Domain Events и StructureMap для проводки. Это прекрасно работает для моих нужд.

  3. На основе других рекомендаций я рекомендую, чтобы интерфейсы репозитория были частью модели, а их реализации - частью инфраструктуры.

  4. Да! Я лично работал над тремя веб-проектами DDD, где сервисы и репозитории были внедрены в презентаторы / контроллеры (ASP.NET/ASP.NET MVC), и это имело большой смысл в нашем контексте.

  1. Хранилище должно быть только для поиска и сохранения сущностей, на этом уровне не должно быть никакой бизнес-логики. Например:

    repository.TransferAmount (сумма, toAccount); // это плохо

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

  3. Да, вы помещаете свою реализацию репозитория на уровень своей инфраструктуры.

  4. Может ли уровень пользовательского интерфейса (контроллера) вызывать методы Repositry напрямую? или мы должны вызвать их из уровня приложений?

Да, я стараюсь следовать этой схеме по большей части:

[UnitOfWork]
public ActionResult MyControllerAction(int id)
{
    var entity = repository.FindById(id);
    entity.DoSomeBusinessLogic();
    repository.Update(entity);
}
Другие вопросы по тегам