如何处理DDD聚合中的getOrCreateIfAbsent



我的需求中有一个情况,我想看看是否有人对此有强烈的意见。

我正在处理的项目要求,给定一个客户,一旦客户将产品添加到购物车中,如果购物车不存在,则必须创建购物车。目前,聚合是Customer,它包含包含Product的Cart。因为这个系统是支持真正的电子商务项目的辅助系统,所以一旦收到"AddProductCommand",就理所当然地创建了Customer和Cart。在这种情况下,如果Customer和Cart还没有创建,则必须创建它们。

我当前的实现在应用程序服务中创建Customer,如果它不存在的话。创建后,我使用customer.addProduct(addProductRequest)传递AddProductRequestAddProductRequest包含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()应该是某种应用程序服务中的行为,而不是在您的一个实体中。

相关内容

  • 没有找到相关文章

最新更新