2012-07-23 44 views
2

當在包含許多CRUD功能的應用程序中實施DDD時,再加上某種類型的web-API,最終會導致在某些情況下可能會使工具變得相對簡單由平臺提供變得更加困難。例如:DDD和CRUD類型的應用程序

說我們有一個用戶對象,你努力不創建一個貧血的領域模型,讓你有更多的表現爲藍本操作:

class User { 
    public void terminateAccount(TeminationReason reason); 
    public void reactivateAccount(); 
} 

上面的類是很好的,因爲它讓我們將賬戶標記爲已終止,並立即設置原因。很明顯,對setEnabled(false)和setTerminationReason(..)的改進。

問題是,可以說我們有一些類似於JAX-RS的Web服務,它可以通過該用戶進行GET/PUT。框架(JAX-RS,JAXB)可以輕鬆地爲我們序列化和反序列化我們的DTO對象。現在,在那裏我們可以做了以前:

entity.setEnabled(dto.isEnabled); 
entity.setTerminationReason(dto.getTerminationReason); 

我們不得不改爲:

if (entity.isEnabled() && !dto.isEnabled()) { 
    entity.terminateAccount(dto.getTerminationReason); 
} else if (!entity.isEnabled && dto.isEnabled) { 
    entity.reactivateAccount(); 
} 

大斷開正在此間域對象的商業化接口,CRUD風格的訪問模式通過RESTful API。既然DDD和REST都是他們自己權利的最佳實踐,那麼每個人在這裏學到了什麼經驗教訓,使代碼不那麼痛苦/重複/等?

PS - 我們正在使用DTO,因爲在幕後使用ORM框架時,實際上將實體序列化爲XML/JSON是個問題,因爲我們無法限制延遲加載。您通常希望通過不屬於域模型的RESTful API(參考URL等)公開不同的屬性。我也接受這方面的建議。

回答

4

我認爲這裏的問題是,您正嘗試使用單個DTO來表示所有API中的User實體。相反,如果每個操作都有單獨的DTO,只包含所需的數據,那麼代碼會更簡單。

例如,TerminateAccount API將有一個DTO,只有終止的原因,你的代碼將僅僅是:

user.terminateAccount(dto.terminationReason); 
+0

@TTar好了,你不只是移動的複雜另一層?客戶現在必須知道根據用戶選擇在「terminateAccount」和「activateAccount」之間調用哪個應用程序服務。最好是將複雜性轉移到應用程序服務中,而不是將其封裝在一起? – plalx 2013-12-05 19:11:22