DDD: совокупная корневая специализация - PullRequest
3 голосов
/ 26 января 2012

У меня есть совокупный корень Order с соответствующими OrderService и OrderRepository.

У меня есть ExtendedOrder с соответствующими ExtendedOrderService и ExtendedOrderRepository.

Например:

class Order {
   int GetOrderId();
}

class ExtendedOrder : Order {
   string GetExtendedInfo();
}

Я бы хотел, чтобы OrderService возвращал оба типа Order и ExtendedOrder в виде списка Order. Но для получения ExtendedOrder следует запросить соответствующий ExtendedOrderService, когда Order имеет тип ExtendedOrder.

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

Ответы [ 4 ]

4 голосов
/ 27 января 2012

Вам не нужен ExtendedOrderService. Просто используйте один OrderService для координации результатов из OrderRepository и ExtendedOrderRepository.

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

3 голосов
/ 30 января 2012

Главный вопрос: для чего это нужно.Я подозреваю, что это связано с каким-то интерфейсом или функциями отчетности.Если это так, то я бы посоветовал не использовать концепции доменной модели для этих запросов.

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

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

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

1 голос
/ 03 февраля 2012

Учитывая, что ExtendedOrder наследует от Order, тогда у вас обычно не было бы ExtendedOrderRepository и ExtendedOrderService - было бы достаточно OrderRepository и OrderService.

ExtendedOrder по-прежнему является Order, поэтому он должен находиться в границах совокупного корня Order и использовать OrderRepository и OrderService.

OrderRepository будет возвращать объекты Order, которые могут быть или не быть Расширенными заказами.ORM, такие как NHibernate, поддерживают это поведение «из коробки».

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

public class Order
{
    public virtual void Process()
    {
        // do processing stuff to an order
        // ...
    }
}

public class ExtendedOrder : Order
{
    public override void Process()
    {
        // do the standard order processing
        base.Process();
        // do extra processing specific to an extended order
        // ...
    }
}


public class OrderService
{
    public void ProcessRecentOrders()
    {
        IEnumerable<Order> orders = orderRepository.GetRecentOrders();
        // orders may include Order and ExtendedOrder objects in the collection...
        foreach (Order in orders)
        {
            // ...but polymorphism ensures that we don't need to know whether order is an ExtendedOrder or an Order
            order.Process();
        }
    }
}

, и при необходимости вы все равно можете явно различать Order и ExtendedOrder:

public void SendOrder(Order order)
{
    // do normal order sending stuff
    orderSender.TransmitOrder(order);
    if (order is ExtendedOrder)
    {
        // do additional stuff required by an ExtendedOrder
    }
}

Этот подход позволяет продолжать создавать другие типы Order (например,SpecialOrder ") без распространения репозиториев и сервисов.

1 голос
/ 01 февраля 2012

Если Extended часть ExtendedOrder действительно является понятием предметной области и частью вездесущего языка (в отличие от чисто пользовательского интерфейса), я бы предпочел композицию над наследованием и сделал бы ее отдельным объектом, ExtendedOrderDetailsнапример.

Он будет частью совокупности Заказа и, следовательно, доступен через Order, предоставленный OrderService.

...