我正在讀上一個SO類似的問題:How update an entity inside Aggregate,但我仍然不知道用戶界面應該如何與骨料內的實體交互。更新實體內的總
比方說,我有User
,有一堆Address
es。用戶是聚合根,而地址只存在於聚合內。
在網頁inteface,用戶可以編輯自己的地址。基本上,會發生什麼情況是:
- 用戶看到它的Web界面
- 他點擊某個地址,並且被重定向到這個頁面上的地址的列表:
edit-address?user=1&address=2
- 在這個頁面上,他得到一個他可以在這裏修改這個地址。
我,我們決定繞開總根,這將是直截了當:
- 我們會直接與加載
Address
其Id
- 我們將更新它,然後將其保存
因爲我們想這樣做的DDD的方式,我們有不同的解決方案:
要麼我們要求用戶憑身份證得到這個地址:
address = user.getAddress(id);
address.setPostCode("12345");
address.setCity("New York");
em.persist(user);
這種方法的問題是,海事組織,該聚合根仍對地址做了什麼沒有更多的控制權。它只是返回一個引用,所以與繞過聚合沒什麼區別。
或者我們告訴彙總更新現有的地址:
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);
這最後的解決方案看起來優雅,但同時也意味着一個地址不能是一個實體。然後,如果有什麼需要被被視爲一個實體,例如因爲聚集中的另一個業務對象有它的參考?
我敢肯定,我失去了一些東西在這裏要正確理解總的概念,它是如何在現實生活中的例子使用,所以請不要猶豫,提出您的建議!
感謝。這確實有道理,儘管我不確定如何實現'changeAddress()'方法。上面的例子是過分簡單化的,地址可能由十幾個字段組成,包括街道名稱,建築物編號,地圖上確切位置的LatLng點等。那麼你建議什麼,將所有這些參數放在方法參數中,或者從表單中創建某種瞬態對象(它也可以是Address對象),並將其作爲參數傳遞給此方法? – Benjamin
我已經爲最常見的場景添加了示例代碼。我不擔心領域的數量--DDD實際上不是關於數據,而是關於關係和管理複雜性。 – kstaruch