2012-01-26 2 views
3

У меня есть сводный корень Order с соответствующими OrderService и OrderRepository.DDD: агрегированная корневая специализация

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

Например:

class Order { 
    int GetOrderId(); 
} 

class ExtendedOrder : Order { 
    string GetExtendedInfo(); 
} 

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

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

+0

Is ExtendedOrder унаследован от заказа? –

+0

Да унаследовано – Ricibald

+0

Ricibald, можете ли вы разместить два определения классов – smartcaveman

ответ

4

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

Дополнительную информацию о роли служб приложений см. В разделе answer to this question. Служба приложений может использовать несколько репозиториев.

3

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

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

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

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

1

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

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

1

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

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

Служба заказаRepository вернет объекты Заказ, которые могут быть или не быть Расширенными ордерами. 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(); 
     } 
    } 
} 

и в случае необходимости вы можете явно различать порядок и 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 
    } 
} 

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

+0

Да, но мне нужны конкретные данные о ExtendedOrder в моем доменном методе – Ricibald