domain-driven-design - DDD - 将项目添加到订单/收据时的价格计算

标签 domain-driven-design business-logic

我正在尝试在我的最新项目中应用 DDD。虽然我在确定将某些业务逻辑/计算放在哪里时遇到问题。

首先,我将描述业务流程,然后我将如何考虑实现它。

业务流程: 它只是将收据项目添加到收据中。但是,元素的价格取决于客户的类型和元素的数量。

即:“A”类型的客户想要购买 2 餐。在他的设置中,他被允许吃 1 顿折扣午餐,但因为他很饿,他吃了 2 顿。第一顿应该是 4 欧元(折扣价),第二顿应该是 6 欧元(全价)。

我的想法是:

Product - 一个实体(具有不同的限界上下文,将仅用作输入参数) - 字段:代码、名称、...、价格集合每个针对不同的客户类型。

ReceiptItem - 实体字段:产品代码、产品名称、数量、价格…… Receipt 作为聚合根 - 字段: 客户(实体)- 包含 ReceiptItems 的集合

在收据上,会有一个方法addItem(Product product, int count),我打算在这个方法中添加正确的价格计算。

回到我们的示例:receipt.addItem('menu1', 2)

所以我会检查客户类型以及允许他打折的午餐数量。鉴于上面的例子,我会看到,他被允许一个。然后我需要获得实际的折扣价,我会直接从公开方法 getCustomersPrice(customerid) 的产品中获得它。 最后,我会将两个收据项目添加到收据中。它们都具有相同的产品代码,但价格不同。 (如果限额为 2 件或更多,我只会以折扣价将一件元素添加到收藏品中,但算上 2 件)。

您认为这是一个好方法吗?我担心将产品作为输入参数传递给 addItem。因为它似乎产生了紧密的耦合。

谢谢。

最佳答案

Receipt 聚合根应该更小:ReceiptReceiptItem,这很好,但是 Customer应该是它自己的聚合根。客户独立于收据而存在,最好是小聚合。

Product 也是此限界上下文中的单独域对象,即使产品也存在于单独的限界上下文中。 Product 也需要在 Receipt 聚合之外。

鉴于存在多个聚合根这一事实,将产品添加到收据的逻辑涉及多个聚合。因此,逻辑不能驻留在 Receipt 聚合或任何其他聚合内。这样的逻辑最好放在域服务中(它可能与Receipt聚合位于同一个包中),例如:

public class ReceiptService {

    void addItem(ReceiptId aReceiptid, ProductId aProductId, int quantity) {

        // business logic to determine price per item
        // ...

        // for each item, forward item creation to receipt:
        receipt.addItem(productIdOrName, priceOfItem);
    }
}

域服务结合各种聚合的数据以确定每件商品的价格。创建 ReceiptItem 并将其插入收据项目集合的内部逻辑最好转发到 Receipt 聚合。

关于domain-driven-design - DDD - 将项目添加到订单/收据时的价格计算,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/58988791/

相关文章:

php - PHP 中的 DDD -> 投影仪 -> 投影仪的注册方法应该在何时何地调用?

django - Django 不适合传达业务逻辑吗?

sql - 业务规则使用检查约束好不好

wpf - mvvm中的businesslogic

java - 在 javadoc 中记录逻辑

e-commerce - 税收引擎示例

java - DDD valueObject 和数据库模式

domain-driven-design - 聚合根引用其他聚合根

python - 每个域模型的目录或每层、角色的目录

namespaces - 跨域(DDD)实体的命名空间