關於domain model的討論已經非常多了,炒炒冷飯,這裡是自己的一些做法。 以workitem(工作流裡的工作項)作為例子
最開始的做法: 乙個實體類叫做workitem,指的是乙個工作項或者稱為任務項 乙個dao類叫做workitemdao 乙個業務邏輯類叫做workitemmanager(或者叫做workitemservice) 主要看看workitemmanager,因為主要邏輯集中在這裡
public class workitemmanager
/*** 提交工作項
* @param workitemid 工作項id
*/public void commitworkitem(string workitemid)
//否則把下一工作項啟用
else
}}
workitem類裡有一些狀態轉換的邏輯,這樣避免直接呼叫get/set屬性方法public class workitem
/*** 完成工作項
*/public void complete()
}
接下來的做法: 三個類不變,將workitemmanager打平,將邏輯移動到workitem這樣帶來的好處是業務邏輯全部被封裝到domain model,domain model之間的互動變得非常的簡單,沒有頻繁的set/get,直接呼叫有業務語義的domain model的方法即可。問題在於單元測試時脫離不了spring的容器,workitemdao需要stub。我覺得這個問題不大,問題是domain model開始變得臃腫,在業務邏輯複雜時**行急劇膨脹。public class workitemmanager
/*** 提交工作項
* @param workitemid 工作項id
*/public void commitworkitem(string workitemid)
}
public class workitem
//否則把下一工作項啟用
else
}}
現在的做法 以上三個類保持不變,增加乙個類workitemexecutor,將業務邏輯移步。
public class workitem
}public class workitemexecutor
/*** 提交工作項
* @param workitemid 工作項id
*/public void commitworkitem(workitem workitem)
//否則把下一工作項啟用
else
}}
將業務邏輯拆分成兩部分,一部分在workitem,另一部分委託給workitemexecutor。實際上是domain model將複雜邏輯的情況重新外包出去。呼叫的時候,面向的介面還是domain model的方法。注意到workitemexecutor和workitemmanager的api是非常相似的。實際可以這樣認為,傳統的方式 client->(business facade)->service(business logic 部分依賴domain model)->data access(dao)。 現在的方式 client->(business facade)->domain model->service->data access(dao)。 另外,在返回client端的查詢的時候還是傾向於直接呼叫dao,而不是通過domain model。 從貧血到充血Domain Model
關於domain model的討論已經非常多了,炒炒冷飯,這裡是自己的一些做法。以workitem 工作流裡的工作項 作為例子 最開始的做法 乙個實體類叫做workitem,指的是乙個工作項或者稱為任務項 乙個dao類叫做workitemdao 乙個業務邏輯類叫做workitemmanager 或者...
從貧血到充血Domain Model
關於domain model的討論已經非常多了,炒炒冷飯,這裡是自己的一些做法。以workitem 工作流裡的工作項 作為例子 最開始的做法 乙個實體類叫做workitem,指的是乙個工作項或者稱為任務項 乙個dao類叫做workitemdao 乙個業務邏輯類叫做workitemmanager 或者...
貧血模型和充血模型
這兩個概念是早些時候martin fowler總結出來的兩種常見模型設計型別,沒有說誰好誰不好,為不同的模型類別選擇合適的場景是設計者的工作。沒有工具本身的問題,只有工具使用者的問題。貧血模型是指領域物件裡只有get和set方法 pojo 所有的業務邏輯都不包含在內而是放在business logi...