【发布时间】:2011-08-25 20:33:46
【问题描述】:
我正在阅读关于 SO:How update an entity inside Aggregate 的类似问题,但我仍然不确定用户界面应如何与聚合内的实体交互。
假设我有一个User,还有一堆Addresses。 User是聚合根,而Address只存在于聚合中。
在网络界面上,用户可以编辑他的地址。基本上,会发生什么:
- 用户在其 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);最后一个解决方案看起来很优雅,但意味着地址不能是实体。那么,如果它需要被视为一个实体,例如因为聚合中的另一个业务对象对它有引用,该怎么办?
我很确定我在这里遗漏了一些东西来正确理解聚合概念以及它在现实生活中的示例,所以请不要犹豫,给你的 cmets!
【问题讨论】:
标签: orm domain-driven-design aggregate aggregateroot