Domain driven design DDD中的标识符与引用

Domain driven design DDD中的标识符与引用,domain-driven-design,aggregate,ddd-repositories,ddd-service,Domain Driven Design,Aggregate,Ddd Repositories,Ddd Service,我有两种情况可以使用实体的id或将其作为引用传递 1) 域服务。例如: class ProductService { public void changePrice(Product product, long newPrice) { // significant calculations involving several Entities here... } // versus public void changePrice(long

我有两种情况可以使用实体的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...
     }
}
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
    }
}
2) 实体。例如:

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...
     }
}
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
    }
}
哪种方法更好?为什么?

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

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


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

+1提及洋葱架构。但我不同意存储库不是域的一部分。存储库的接口应该在域内定义。实现是外部关注的问题。也就是说,定义为域的一部分的存储库接口应该使用普遍存在的语言,也就是说,不要像
ProductRepository
ICCustomerRepository
那样被调用,而是
Products
VIPCustomers
@DennisTraub感谢您的评论。我对你的观点做了一点更新。在这种情况下,我能想到一个问题。比如说,我对订单进行了一些产品验证。在这种情况下,域的客户端可以轻松地传递一个有效的产品并更改它,从而使订单无效。我开始想,如果你需要整个引用,你可能只需要一个更深层的聚合(里面有产品)或在域服务中定义一个操作(出于同样的原因,它应该接受id而不是引用)。或者这里有一个建模问题(也许我不想做这种验证)。