2011-09-19 5 views
4

Я хотел бы задать вопрос о функциях DDD. Допустим, у нас есть два агрегата, и каждый из них содержит адрес объекта-объекта. В соответствии с Eric Evans DDD мы должны изолировать агрегаты друг от друга, поэтому совокупный корень первого агрегата не может иметь ссылку на адрес. Честно говоря, для меня это не имеет смысла, поэтому вопрос заключается в том, как разрешить такую ​​ситуацию? Какой агрегат должен содержать адрес?DDD Агрегаты и объекты значений

Thanks

ответ

9

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

В большинстве случаев проблемы объекта entity и value сводятся к людям, имеющим проблемы с дублированием данных. Мы были настолько обучены мыслить в 3-й нормальной форме одной канонической модели. DDD борется с неизбежной сложностью, которая возникает благодаря принуждению к дублированию там, где это необходимо, и разрешению понятий, которые когда-то считались одними из многих.

Надеется, что это помогает

+0

Не могли бы вы привести пример как ограниченного, так и неограниченного контекста? Для лучшего понимания. – madcyree

+1

Если у вас ограниченный контекст заказа и ограниченный контекст клиента, вы хотите иметь независимые адреса. Клиенты и заказ AR находятся в разных контекстах. Если у вас есть рекламные AR-файлы для заказа и доставки, они находятся в одном контексте, и вы можете использовать один и тот же объект значения адреса. –

+0

Спасибо за объяснение :) – madcyree

8

Значения объекта является объектом, который описывает некоторые характерный или атрибута, но не несет никакой концепции идентичности.

Поскольку у него нет концептуальной идентичности, вы не можете «ссылаться» или «иметь ссылку» на него. Вы можете только «содержать» его. Допустим, у вас есть Пользователь и пользователь имеет возраст. Возраст - это объект ценности. Если Иоанну исполнилось 25 лет, а Джейн тоже 25, они не ссылаются на тот же возраст. Возраст Йонха просто равен возрасту Джейн. Поэтому, если ваш адрес действительно представляет собой объект Value, вы не нарушаете никаких границ Aggregate. У ваших общих корней просто одинаковые адреса. Даже если у вас есть техническая ссылка на java/C# для Address, это не имеет значения, потому что объект Value является неизменным большую часть времени.

Трудно ответить на ваш вопрос, хотя и не зная, в какой области вы работаете. Но обычно адрес не обязательно должен быть Объектом Value. Эрик Эванс упоминает в своем book, что Домены почтовой службы и Доставки доставки будут обрабатывать адрес как объект. Электрическая компания, которая отправляет техников, должна понимать, что два вызова службы от «123 Elm St» на самом деле поступают с одного и того же адреса, и ему нужно только отправить одного специалиста. Адрес или «Жилье» - это Сущность в этом случае.

2

Агрегаты относятся только к ДАННЫЕ МОДИФИКАЦИЯ. Никакой два агрегата не должны позволять изменять одни и те же данные. Поскольку объект Value неизменен, он предотвращает этот сценарий. Поэтому для двух или более агрегатов вполне справедливо использовать один и тот же объект Value, поскольку это структура данных только для чтения, а агрегат не заботится о модели чтения.

Address a = new Address("1111 ABC Ave."); 
person.setAddress(a); 
letter.setAddress(a); 

person.getAddress().change("2222 XYS Ave.") // THIS IS ILLEGAL SINCE Address is a VO (immutable) 

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

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

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


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

Say для доставки вам нужно:

Address 
{ 
    Number; 
    Unit; 
    Street; 
    State; 
    Country; 
    PostalCode; 
} 

Но место вам нужно:

Address 
{ 
    Number; 
    Unit; 
    Latitude; 
    Longitude; 
} 

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

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

Смежные вопросы