我在SO上读了一个类似的问题:如何更新Aggregate中的实体,但我仍然不确定用户界面应该如何与聚合内的实体进行交互.
假设我有User一堆,有一堆Addresses.用户是聚合根,而地址仅存在于聚合中.
在Web界面上,用户可以编辑他的地址.基本上,会发生什么:
edit-address?user=1&address=2我决定绕过聚合根,这很简单:
Address它Id因为我们想用DDD方式做,所以我们有不同的解决方案:
我们要求用户通过Id获取此地址:
address = user.getAddress(id);
address.setPostCode("12345");
address.setCity("New York");
em.persist(user);
这种方法的问题是,IMO,聚合根仍然没有更多的控制地址的作用.它只返回对它的引用,因此与绕过聚合没有太大区别.
或者我们告诉聚合更新现有地址:
user.updateAddress(id, "12345", "New York");
em.persist(user);
现在,聚合控制了对此地址所做的操作,并且可以采取任何必要的操作来更新地址.
或者我们将地址视为值对象,我们不更新我们的Address,而是删除它并重新创建它:
user.removeAddress(id);
address = new Address();
address.setPostCode("12345");
address.setCity("New York");
user.addAddress(address);
em.persist(user);
最后一个解决方案看起来很优雅,但意味着地址不能是实体.然后,如果需要将其视为实体,例如因为聚合中的另一个业务对象具有对它的引用,该怎么办?
我很确定我在这里遗漏了一些东西,以正确理解聚合概念以及它如何在现实生活中使用,所以请不要犹豫,发表您的意见!