【问题标题】:Identifier vs. Reference in DDDDDD 中的标识符与引用
【发布时间】:2014-09-15 19:10:21
【问题描述】:

我有两种情况可以使用实体的 id 或将其作为参考传递。

1) 域服务。示例:

class ProductService {
     public void changePrice(Product product, long newPrice) {
          // significant calculations involving several Entities here...
     }
     // versus
     public void changePrice(long productId, long newPrice) {
          Product product = productRepository.get(productId);
          // significant calculations involving several Entities here...
     }
}

2) 实体。示例:

class Order {
    public void addItem(Product product, long quantity) {
        // do stuff
    }
    // versus
    public void addItem(long productId, long quantity) {
        Product product = Registry.productRepository().get(productId);
        // do stuff
    }
    // or even maybe this ugly version?
    public void addItem(ProductRepository productRepository, long productId, long quantity) {
        Product product = productRepository.get(productId);
        // do stuff
    }
}

哪种方法更好,为什么?

【问题讨论】:

    标签: domain-driven-design aggregate ddd-repositories ddd-service


    【解决方案1】:

    我喜欢 Onion Architecture 关于如何从概念上思考如何保护您的域免受外部影响的观点。

    IMO,最好将存储库保留在域之外。让域外的层解析域实体,然后在域内使用它们

    所以,我显然更愿意看到直接使用Product 的示例(参考)。存储库的实现不在域中。域不应该被 id、配置或持久性弄得杂乱无章。相反,它应该直接关注领域问题,并且尽可能清晰。

    【讨论】:

    • +1 用于提及洋葱架构。但我不同意存储库不是域的一部分。存储库的接口应在域内定义。实现是一个外部问题。话虽如此,定义为域一部分的存储库接口应该使用通用语言,即不被称为 ProductRepositoryICustomerRepository 之类的东西,而是 ProductsVIPCustomers
    • @DennisTraub 感谢您的评论。我对你的观点做了一点更新。
    • 在这种情况下我能想到一个问题。假设我对产品的订单进行了一些验证。在这种情况下,域的客户端可以轻松传递有效的产品并对其进行更改,从而使订单无效。我开始认为,如果您需要整个引用,则可能只需要更深层次的聚合(内部包含 Product)或在域服务中定义一个操作(出于同样的原因,它应该接受 id 而不是引用)。跨度>
    • 或者这里只是一个建模问题(也许我不应该做这种验证)。
    猜你喜欢
    • 1970-01-01
    • 2010-09-19
    • 2011-07-30
    • 1970-01-01
    • 2015-12-01
    • 1970-01-01
    • 2015-07-09
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多