【问题标题】:DDD: aggregate root specializationDDD:聚合根特化
【发布时间】:2012-02-19 08:45:02
【问题描述】:

我有一个聚合根 Order,对应的 OrderServiceOrderRepository

我有一个ExtendedOrder,对应的ExtendedOrderServiceExtendedOrderRepository

例如:

class Order {
   int GetOrderId();
}

class ExtendedOrder : Order {
   string GetExtendedInfo();
}

我想让OrderServiceOrderExtendedOrder 作为Order 的列表返回。但是要获得ExtendedOrder,当Order 的类型为ExtendedOrder 时,它应该询问相应的ExtendedOrderService

是否有可能获得这种行为? 一个聚合根扩展另一个聚合根是否合法?

【问题讨论】:

  • ExtendedOrder 是否继承自 Order?
  • Ricibald,你能发布两个类的定义吗

标签: inheritance service domain-driven-design


【解决方案1】:

您不需要 ExtendedOrderService。只需使用一个 OrderService 来协调来自 OrderRepository 和 ExtendedOrderRepository 的结果。

有关应用程序服务角色的更多信息,请参阅answer to this question。 一个应用服务可以利用多个存储库。

【讨论】:

    【解决方案2】:

    主要问题是,你需要它做什么。我怀疑它与某种 UI 或报告功能有关。如果是这种情况,我的建议是不要对这些查询使用域模型概念。

    换句话说,将领域模型概念与报告相关的查询(在 UI 上呈现结果毕竟是一种报告形式)分开,这对于保持一致性和实现对复杂业务逻辑的控制非常有用。在某些时候未能进行这种分离总是会导致调整域模型以满足某种 UI 或报告的要求,而这不应该发生。

    在您的情况下,我只需准备一个忽略聚合并选择我需要的所有数据的查询。当然,当要对结果执行一些业务操作时,它应该使用领域模型。毕竟聚合负责保持一致性,唯一有可能破坏一致性的事情就是更新数据——读取数据不会导致变化,因此在我看来使用聚合进行读取有点毫无意义。

    综上所述——在大多数情况下与报告相关的功能不应该导致领域模型业务概念的调整。

    【讨论】:

      【解决方案3】:

      如果ExtendedOrderExtended 部分真的是一个领域概念并且是通用语言的一部分(而不是纯粹的UI 商品),我会更喜欢组合而不是继承,并使其成为一个单独的实体,ExtendedOrderDetails例如。

      它将是 Order 聚合的一部分,因此可以通过OrderService 提供的Order 访问。

      【讨论】:

        【解决方案4】:

        鉴于 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”),而不会增加存储库和服务。

        【讨论】:

        • 是的,但我需要在我的域方法中提供有关 ExtendedOrder 的特定数据
        猜你喜欢
        • 2016-03-21
        • 1970-01-01
        • 2010-12-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2016-03-29
        • 2015-01-04
        相关资源
        最近更新 更多