最近在上下班擠公交的時間細閱clean code(代碼整潔之道),再次佩服bob大叔幽默的文筆,獨到的觀點和了解視角。最讓我耳目一新的是bob大叔對資料結構和對象的解釋。
總的說來資料結構指的就是資料的載體,暴露資料,而幾乎沒有有意義的行為,你應該在尖叫這不是貧血類?的确這和我們的貧血類很相似。最常見的應用在分布式服務,以wcf,webservice,reset之類的分布式服務中不可或缺的資料傳輸對象(dto)模式,dto(request/response)就是一個很典型的資料載體,隻存在簡單的get,set屬性,并且更傾向于作為值對象存在。而對象則剛好相反作為面向對象的産物,必須封裝隐藏資料,而暴露出行為接口,ddd中領域模型傾向于對象不僅在資料更多暴露行為操作自己或者關聯狀态。
雖然資料結構和對象之間看是細微的差别卻導緻了不同的本質差別:使用資料結構的代碼便于在不改動現在資料結構的前提下添加新的行為(函數),面向對象代碼則便于不改動現 有函數的前提下添加新的類。換句話說就是資料結構難以添加新的的資料類型,因為需要改動所有函數,面向對象的代碼則難以添加新的函數,因為需要修改所有的類。在任何一個複雜的系統都會同時存在資料結構和對象,我們需要判斷的是我們需要的是需要添加的新的資料類型還是新的行為函數。
在則就是迪米特法則,或被譯為最小知識原則,不和陌生人說話:子產品不應該了解他所操作的對象的内部情形,關于對象的隐藏,更細緻的了解為一個對象a的方法f,應該也隻能調用對象為下列範圍内:
對象a的屬性字段
對象a持有的對象
方法參數傳入的對象
在方法f中定義的臨時對象
方法不應和任何調用方法傳回的對象操作,換句話之和朋友說話,不和陌生人說話。比如:ctxt.getoptions().getsearchdir().getabsolutepath(),就是迪米特法則的反例模式。
但目前迪米特法則的前提是對象,如果是資料結構,沒有什麼行為,則他們自然會暴露其内部資料結構,迪米特法則也失效了。
隐藏作為面向對象主要特性中的最重要特性,封裝隐藏是面向對象中最重要的特性,一個好的面向對象代碼肯定是對對象的内部細節做到很好的隐藏封裝,封裝過後才有是多态,委派之類的。一個好的面向對象的代碼一定是具有很好的隐藏封裝,易于測試,不穩定因素往往集中在一處很小或者固定的位置,不穩定因素的變更不會導緻更大面積的修改擴散。
最後推薦下一本書籍,值得在空閑時間看看,不能保證看完代碼就一定寫出整潔的代碼,做到童子軍軍規“每次簽入的代碼比簽出的更整潔”,更不會像優美的散文,這需要在項目實踐中不斷練習發現,但對代碼品質意思有着引導作用。
總感覺自己的技術還差得很遠,是以我總是限制自己抽出可用的時間看些書籍,從不同的視角,不同的領域或者一些思想的提升和沉澱。
關于面向對象原則随筆還有:
<a href="http://www.cnblogs.com/whitewolf/archive/2012/05/12/2497419.html">(轉載)一些軟體設計的原則</a>
<a href="http://www.cnblogs.com/whitewolf/archive/2012/06/02/2532244.html">軟體架構設計箴言了解</a>