Domain driven design DDD中的标识符与引用
我有两种情况可以使用实体的id或将其作为引用传递 1) 域服务。例如: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
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而不是引用)。或者这里有一个建模问题(也许我不想做这种验证)。