DDD: агрегаты и субагрегаты

У меня довольно сложный агрегат с агрегированным корнем Order. Он содержит сущности (например, OrderItem), которые не имеют смысла вне агрегата. Но есть также объекты, которые должны быть частью этого агрегата, но также имеют смысл за пределами этого агрегата (например, ShippingMethod или Invoice).

Правильно ли иметь репозиторий для этого сложного агрегата (загрузка всего агрегата по корневому идентификатору), а также иметь репозиторий CRUD для управления возможными методами доставки и еще один репозиторий для перечисления счетов-фактур?

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


person Matěj Koubík    schedule 18.07.2013    source источник
comment
Помогает ли это: stackoverflow.com/questions/17611635/   -  person Eben Roux    schedule 18.07.2013
comment
Наличие просто объекта-значения, представляющего данные из ShippingMethod, кажется хорошей идеей, спасибо.   -  person Matěj Koubík    schedule 18.07.2013


Ответы (1)


Вы можете рассматривать «агрегат, который является частью другого агрегата», как «агрегат содержит ссылку на другой агрегат».

Например

public class Order {
    private Invoice invoice;
}

<class name="Order" table="T_ORDER">
    <one-to-one name="invoice" column="INVOICE_ID" />
</class>

Если и Order, и Invoice являются агрегированными в этом контексте, у меня будут OrderRepository и InvoiceRepository. Вы можете получить Order, используя

orderRepository.findBy(orderId)

И вы можете получить счет-фактуру, используя

invoiceRepository.findBy(invoiceId) 

or

Order order = orderRepository.findBy(orderId);
Invoice invoice = order.getInvoice();

И есть известная статья о том, как создавать агрегаты (http://dddcommunity.org/library/vernon_2011/), который предлагает реализовать эти отношения с помощью ссылки на личность.

public Class Order {
    private InvoiceId invoiceId;
}

<class name="Order" table="T_ORDER">
    <component name="invoiceId">
        <property name="value" column="INVOICE_ID" />
    </component>
</class>

Вы можете получить Заказ, используя

orderRepository.findBy(orderId)

И вы можете получить счет-фактуру, используя

invoiceRepository.findBy(invoiceId) 

or

Order order = orderRepository.findBy(orderId);
Invoice invoice = invoiceRepository.findBy(order.getInvoiceId()); 
person Yugang Zhou    schedule 18.07.2013
comment
Как реализовать это с помощью ORM (я использую php и доктрину)? Разве наличие ссылочного идентификатора непосредственно в сущности не считается антипаттерном? - person Matěj Koubík; 18.07.2013
comment
Я не знаком с php и доктриной. Но это может быть реализовано с использованием обычного однозначного сопоставления с Hibernate в Java (в случае агрегированной ссылки Aggregate). Я не уверен, что ссылка на id является анти-шаблоном, есть ли статьи или ресурсы, в которых это обсуждается? - person Yugang Zhou; 18.07.2013
comment
Doctrine во многом вдохновлен Hibernate. Я имею в виду, что наличие целочисленного атрибута, такого как invoiceId в сущности, является антипаттерном, согласно docs.doctrine-project.org/projects/doctrine-orm/en/latest /. Изменить: теперь я вижу, что вы имели в виду не целое число, а объект значения, содержащий только идентификатор. - person Matěj Koubík; 18.07.2013
comment
Ссылочный идентификатор - это объект значения. Теперь вы должны выполнить два запроса вместо перехода от Order к Orderitems. - person JefClaes; 18.07.2013
comment
Но я бы хотел иметь Order.invoice_id в db в качестве внешнего ключа из-за упрощения отчетности. Есть ли способ сопоставить его с VO в модели предметной области и со связанным объектом в модели отчетности? Или мне следует разделить сущности домена и сущности постоянства (они будут почти одинаковыми)? - person Matěj Koubík; 19.07.2013
comment
@ MatějKoubík Обновлен ответ для добавления примера отображения гибернации. Лучше не разделять модели домена и объекты сохраняемости, см. stackoverflow.com/questions/17650073/. - person Yugang Zhou; 19.07.2013
comment
Но тогда я не могу использовать HQL для отчетности, потому что invoice_id - это целое число, а не ссылка на сущность Invoice. Или? - person Matěj Koubík; 19.07.2013
comment
Честно говоря, у меня тот же вопрос, если использовать регистр идентификации. Я читаю статью Вернона, надеюсь найти ключ к разгадке. - person Yugang Zhou; 19.07.2013