我的需求中有一个情况,我想看看是否有人对此有强烈的意见。
我正在处理的项目要求,给定一个客户,一旦客户将产品添加到购物车中,如果购物车不存在,则必须创建购物车。目前,聚合是Customer,它包含包含Product的Cart。因为这个系统是支持真正的电子商务项目的辅助系统,所以一旦收到"AddProductCommand",就理所当然地创建了Customer和Cart。在这种情况下,如果Customer和Cart还没有创建,则必须创建它们。
我当前的实现在应用程序服务中创建Customer,如果它不存在的话。创建后,我使用customer.addProduct(addProductRequest)
传递AddProductRequest
。AddProductRequest
包含Cart id和Product id。问题就在这里。一旦进入Customer聚合,如果购物车不在那里,我就必须创建它。因此,基本上,我没有一个addCart
在客户与购物车实体,我先调用,然后调用addProduct
。如果购物车不在Customer聚合中,我需要创建它,然后将Product添加到其中。要做到这一点,我不创建任何工厂,因为我不想有一个静态方法,使测试复杂化,我也不能只是在聚合中创建一个新的工厂。我只是在一个受保护的方法中使用new操作符创建了Cart实体,我在测试时重写了这个方法,以验证我在那里做了什么。
所以我的问题是,这是一个有效的方法吗?在我的脑海中,要将产品添加到购物车中,应该首先将购物车添加到客户中,如果没有,则失败。要这样做,我需要向应用程序服务添加逻辑,首先,我将询问Customer是否有一个具有该id的Cart,否则创建它,并在添加Product之前将其添加到Customer。我可以添加一个给定此请求的域服务,但随后我需要注入工厂以在其中创建Cart,当我在几个地方读到域服务不应该注入任何工厂时,这应该是应用程序服务的工作。
我可以这样做,但项目将来会变得更复杂,因为还会有另一个层,其中可以添加产品,如果AddVoucherCommand
消费时不存在,还必须创建客户、购物车和产品的代金券列表。在这种情况下,如果我不想在模型中创建实体,我就需要在应用程序/域服务中检查每个聚合或实体内部是否有必要的实体,我认为这不是非常友好的DDD,或者只是继续做我现在正在做的事情。也就是说,在调用addXXXX
方法之前,每个聚合/实体负责创建必要的实体。
一些简化的代码来解释我现在正在做的事情和我将来要做的事情:
public class CustomerService {
public void addVoucher(AddVoucherRequest addVoucherRequest) {
Customer customer = customerRepo.load(customerId);
customer.addVoucher(addVoucherRequest);
customerRepo.save(customer);
}
}
public class Customer() {
public void addVoucher(AddVoucherRequest addVoucherRequest) {
Cart cart = getOrCreateIfAbsent(addVoucherRequest.getCartId());
cart.addVoucher(addProductRequest);
}
private Cart getOrCreateIfAbsent(long cartId){
Optional<Cart> cart = carts.stream().filter(cart -> cart.getId() == cartId).findFirst();
return cart.orElseGet(() -> {
Cart newCart = createCart(cartId);
carts.add(newCart);
return newCart;
}
}
protected Cart createCart(long cartId) {
return new Cart(cartId);
}
}
public class Cart() {
public void addVoucher(AddVoucherRequest addVoucherRequest) {
Product product = getOrCreateIfAbsent(addVoucherRequest.getProductId());
product.addVoucher(addVoucherRequest);
}
private void getOrCreateIfAbsent(long productId) {
Optional<Product> product = products.stream().filter(product -> product.getId() == productId).findFirst();
return product.orElseGet(() -> {
Product newProduct = createProduct(productId);
products.add(newProduct );
return newProduct ;
}
}
protected Product createProduct(long productId) {
return new Product(productId);
}
}
有什么建议吗?
谢谢!
选择等待客户订购某些东西以在新系统中创建他/她,而不是预先从遗留系统导入所有客户,这是一个纯粹的技术决策,在我看来,这与您的域无关。
因此,它不应该以任何方式影响您设计域对象的方式-据我所知,getOrCreateIfAbsent()
应该是某种应用程序服务中的行为,而不是在您的一个实体中。