我有一个聚合根Order
,其对应的OrderService
和OrderRepository
。
我有一个ExtendedOrder
,对应ExtendedOrderService
和ExtendedOrderRepository
。
例如:
class Order {
int GetOrderId();
}
class ExtendedOrder : Order {
string GetExtendedInfo();
}
我希望OrderService
将Order
和ExtendedOrder
类型作为Order
列表返回。但要获得ExtendedOrder
,当ExtendedOrderService
类型为Order
时,它应该询问相应的ExtendedOrder
。
是否有可能获得此行为? 让聚合根扩展另一个聚合根是否合法?
答案 0 :(得分:4)
您不需要ExtendedOrderService。只需使用一个OrderService来协调OrderRepository和ExtendedOrderRepository的结果。
有关Application Services角色的更多信息,请参阅answer to this question。 应用程序服务可以使用多个存储库。
答案 1 :(得分:3)
主要问题是,你需要什么?我怀疑它与某种UI或报告功能有关。如果是这种情况,我建议不要对这些查询使用域模型概念。
换句话说,单独的域模型概念非常适合保持一致性并实现对复杂业务逻辑的控制,而不是报告相关的查询(在UI上显示结果毕竟是一种报告形式)。在某些时候未能做到这种分离总是导致调整域模型以满足某种UI或报告的要求,这不应该发生。
在你的情况下,我只是准备一个忽略聚合的查询,并选择我需要的所有数据。当然,当要对结果执行某些业务操作时,它应该使用域模型。在所有聚合都负责保持一致性之后,唯一有机会混淆一致性的是更新数据 - 读取数据不会导致更改,因此在我看来使用聚合读取有点毫无意义。
总结 - 大多数情况下与报告相关的功能不应导致域模型业务概念的调整。
答案 2 :(得分:1)
如果Extended
的{{1}}部分确实是一个域概念,而且是普遍存在的语言的一部分(而不是纯粹的UI商品),我赞成组合优于继承,并使其成为一个独立的实体,例如ExtendedOrder
。
它将成为订单汇总的一部分,因此可以通过ExtendedOrderDetails
提供的Order
访问。
答案 3 :(得分:1)
鉴于ExtendedOrder继承自Order,那么您通常不会有ExtendedOrderRepository和ExtendedOrderService - OrderRepository和OrderService就足够了。
ExtendedOrder仍然是一个Order,因此它应该位于Order聚合根的边界内,并使用OrderRepository和OrderService。
OrderRepository将返回Order对象,这些对象可能是也可能不是扩展订单。诸如NHibernate之类的ORM支持这种开箱即用的行为。
以这种方式工作有助于实现更优雅的代码和更少的重复。代码可能如下所示:
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
}
}
此方法可让您继续创建其他订单类型(例如“SpecialOrder”),而不会增加存储库和服务。