關於貧血模型

GUANPEI發表於2008-07-05
關於貧血模型
貧血模型的問題與所謂專家原則以及分層原則直接相關。物件導向系統的主要任務就是安排物件系統的責任劃分以形成合理的協同關係;專家原則是說,某個功能、行為應該分配給持有相關資訊最完整的物件;顯然,專家原則與關於高內聚的思想相一致。分層原則是就係統的大結構而言,企業級應用以業務邏輯為中心,向下是持久層,向上是表現層。

設計原則的適用要考慮具體的條件,這是軟體系統設計的本質。抽象地來看,專家原則與分層原則存在矛盾:按照分層原則,系統會出現許多物件位於不同的層:持久層物件是所有資料的來源,那麼教條地套用專家原則會得出這樣的結論:既然持久層的PO擁有完備的資料(資訊),它自然應該做所有的事情,包括相關邏輯以及渲染。這顯然不合理。實際上基本合理的安排是:分層原則導致出現不同的層中的物件群;專家原則主要是在業務邏輯層,適用於主要以功能為特徵、具有豐富的外部行為的功能性物件,而不適用於實體Bean這樣的東西;後者是一種資訊結構,Getter和Setter不能夠作為某種行為,甚至有人主張乾脆將成員置為Public。

由此可見,分層應該是軟體系統宏觀的構造規律和原則,專家原則則要微觀一些。認識和把握這一點比之原則本身更為重要。體系結構之所以被稱為Art,與這種變化、變通的準確把握有關。

所謂對貧血模型的指責也就是對機械地分層的某種後果的批判。其實,抽象地談論某種設計原則的是是非非幾乎肯定沒有意義,事情的實質仍然在於條分縷析地界定出各自的約束條件、適用條件。

首先一點是,不能夠過分地無視分層原則,這是軟體系統構造迄今為止最廣泛適用的原則之一。其次,關於物件的行為,我們起碼可以給出一個最基本的劃分:

物件本身所固有的、內在的、使其成為它自己的行為,這些行為是物件定義的一部分。它們高於物件的Getter和Setter,但仍然屬於基礎行為。
基於物件的第一類行為集合,需要物件與其它物件協同工作才能夠完成的動作
就實現層面上也有一個劃分:
物件完成這個行為並不需要依賴於某種狹隘的技術就可以完成。比如它的某些成員經過數學運算之後的一個結果。
與之相反,物件完成這個行為需要依賴於某種狹隘的技術才可以完成,比如某種渲染,需要依賴於不同的GUI表現方式。
有了這個基本劃分,很自然地,如果符合兩類劃分中的第一種劃分,可以考慮將這些行為注入物件,為實體bean充血。當然,以上的做法並不是給出了一個解決此類矛盾的靈丹妙藥,不同的條件下仍然有其它的做法會比較合適。比如對於第一種劃分中的第一類物件,一個物件處理器(EntityHandler)可能很好地解決問題,handler本身形成一個具有抽象層次的體系來處理物件共有的以及特殊的行為,但它們基本上不涉及物件之間需要高度配合才能完成的事情,那些事情由更上層的組合邏輯才能夠完成。Handler是實體的外部相對單純的專門的操作者,它們與物件的關係非常緊密以至於執行時與實體成對存在;我們可以認為它們處於邏輯層的底部,緊貼持久層之上。



相關文章