Design patterns 贫血领域模型是否意味着你可以';t将实用程序/支持类用作;“助手”;对于您的域模型?

Design patterns 贫血领域模型是否意味着你可以';t将实用程序/支持类用作;“助手”;对于您的域模型?,design-patterns,domain-driven-design,Design Patterns,Domain Driven Design,根据Fowler的贫血域模型概念为: 软件领域模型,其中 业务逻辑在外部实现 域对象 及 在这种模式下,逻辑通常是 在单独的类中实现 转换域的状态 物体。福勒称之为外部的 类事务脚本 如果我们以购物车为例,购物车对象将是域对象。但要将购物车处理到最终订单和收据,需要检查订单库存并处理信用卡付款。很多这类东西都需要实用程序类,因为在Cart对象内部执行所有操作都意味着Cart类将非常庞大和麻烦。那么,这是否意味着本例中的购物车将是一个贫乏的领域模型,根据上述定义,这些实用程序类将是“事务脚本”?领

根据Fowler的贫血域模型概念为:

软件领域模型,其中 业务逻辑在外部实现 域对象

在这种模式下,逻辑通常是 在单独的类中实现 转换域的状态 物体。福勒称之为外部的 类事务脚本


如果我们以购物车为例,购物车对象将是域对象。但要将购物车处理到最终订单和收据,需要检查订单库存并处理信用卡付款。很多这类东西都需要实用程序类,因为在Cart对象内部执行所有操作都意味着Cart类将非常庞大和麻烦。那么,这是否意味着本例中的购物车将是一个贫乏的领域模型,根据上述定义,这些实用程序类将是“事务脚本”?

领域驱动设计的一个关键概念是创建一个丰富的设计,传达并反映其领域专家(业务用户)的行话。然后,您希望您的代码成为该域模型的表达式。(请参阅中的“通用语言”和“模型驱动设计”)

当您这样做时,您将为您的实体(类)创建名称,以反映业务用户可能如何描述它们。此外,您将在这些类上创建也反映域的方法

考虑到这一点,考虑你如何看待你的“助手”或“实用”类可能会有帮助。使用您的一些描述,您可能有如下类和方法:

product = GetProduct(data.productId);
shoppingCart.add(product);
receipt = customer.Purchase(shoppingCart);
您的客户。购买方法可能会执行以下操作:

creditCard = this.getCreditCart(creditCardNumber);
purchaseNumber = creditCard.Charge(shoppingCart.Total);
我意识到这些例子并不完整,甚至不完全准确,但我希望这个想法是有帮助的

回答您最初的问题——是的,有一个实用工具支持类是可以的。但是,您需要创建这些支持类,并将它们映射到真正的域实体。在与用户进行一些工作之后,您可能将能够创建比事务脚本实体更多的有意义的域实体


希望这有帮助。祝你好运

正如Chris所说,如果实用程序支持类映射到从用户语言中发现的实际域实体,那么可以使用实用程序支持类。有时很多“助手类”都是模型贫乏的症状,如果它们与主要具有setter和getter的类相关(在这些场景中,助手是从没有正确分配给域对象的行为中成长起来的)。

请原谅我的好奇,但问题是,正如我所理解的,是关于贫血的域模型,它完全禁止在域类中使用上述Purchase()之类的方法。使用贫血的域模型,域类除了getter/setter之外什么都没有,最终会在域类之外实现所有(!)行为。因此,根据上述假设,采用贫血域模型将迫使您使用帮助器/实用程序类,因为您没有其他选择!为什么不两全其美:域模型中的通用算法和域外的其他算法!Stefan@struppi-你为什么说像上述购买()这样的方法是被禁止的?此方法可能不仅仅是获取/设置,因为它将包含执行购买的业务逻辑。