DDD: Какое поведение я должен применять к объекту домена? - PullRequest
17 голосов
/ 16 октября 2011

Моя команда очень старается придерживаться Domain Driven Design как архитектурной стратегии. Но, в большинстве случаев, наши доменные сущности довольно враждебны. Мы хотели бы, чтобы на наших доменных объектах было больше поведения бизнеса / домена.

Например, Active Record предоставляет доступ к данным для объекта. Мы не хотим этого, потому что мы счастливо используем шаблон хранилища для доступа к данным.

Кроме того, мы разрабатываем наше программное обеспечение как ТВЕРДЫЕ (пять принципов разработки программного обеспечения, которые собрал дядя Боб). Поэтому для нас важно, чтобы при разработке наших сущностей мы обращали внимание на единую ответственность, открытую-закрытую, liskov, сегрегацию интерфейса и инверсию зависимостей.

Итак, какие виды поведения мы должны включать? От каких видов мы должны держаться подальше?

Ответы [ 4 ]

23 голосов
/ 29 августа 2012

Прошел почти год с тех пор, как я задал этот вопрос, и я и моя команда с тех пор многому научились.Вот как я бы ответил на этот вопрос сегодня:

Домен должен представлять (в коде), чем занимается бизнес (или в реальной жизни).Таким образом, доменные объекты - это артефакты или акторы, обнаруженные в этом реальном бизнесе.Какое поведение имеют эти артефакты и актеры Rea-Life?Все это.В свою очередь, какое поведение ДОЛЖНЫ иметь доменные сущности на них?Все это.

Например, в реальной жизни менеджер может нанять нового сотрудника.Представление домена должно включать такие объекты, как «менеджер» и «новый сотрудник».Менеджер - актер, здесь.

//newEmployee comes from somewhere else... possibly the UI
//someManagerId comes from the logged in user
var manager = _repository.Get<Manager>(someManagerId);
manager.Hire(newEmployee);

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

//newEmployeeService comes from somewhere else... possibly injected using IOC
newEmployeeService.Create(newEmployee, someManagerId);

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


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

  1. Мы стараемся, когда это возможно, использовать субъекты-актеры, чтобы выразить человека или предмет, который выполняет действие.
  2. Актеры имеютметоды, которые выражают действия, которые они могут выполнять
  3. Когда требуется служба, она внедряется в качестве аргумента в метод, в котором она используется.
  4. Мы запускаем события домена, используя BlingBag для каждого метода в каждой сущности домена, чтобы обеспечить расширяемость и дать сущностям возможность самосохранения.
3 голосов
/ 08 марта 2012

Если вам нужно спросить, какое поведение вы должны применить к объекту домена, то вам, вероятно, не нужен DDD. Я пытаюсь быть полезным здесь, потому что мне было очень больно пытаться приспособить DDD к месту, которому он не принадлежал.

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

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

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

1 голос
/ 17 октября 2011

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

проверка перед сохранением. проверка перед переходом в новое состояние. Например, корневая сущность совокупного порядка может проверить свое внутреннее состояние и свои дочерние совокупности, прежде чем перейти в состояние Отправлено. свести к минимуму получить набор свойств и максимально использовать объекты значения. Во-первых, это обогащает модель поведением. сущности становятся более описательными. во-вторых, вы реже переводите свою сущность в недопустимое состояние, если вы должны использовать методы объекта-значения, такие как метод ApplyAdress, для сущности-человека, которая принимает объект значения-адреса, как в параметре.

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

0 голосов
/ 08 марта 2012

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

В системе онлайн-покупок вы можете добавить товар в корзину. Поэтому класс Cart должен выглядеть так:

public class Cart
{
    //...

    public void AddProduct(Product product)
    {
        ...code to add product to cart.
    }
}

Можно утверждать, что метиды должны отражать варианты использования.

...