最近在上下班擠公交的時間細閱Clean Code代碼整潔之道),再次佩服Bob大叔幽默的文筆,獨到的觀點和理解視角。最讓我耳目一新的是Bob大叔對資料結構和對象的解釋。
總的說來資料結構指的就是資料的載體,暴露資料,而幾乎沒有有意義的行為,你應該在尖叫這不是貧血類?的確這和我們的貧血類很相似。最常見的應用在分布式服務,以wcf,webservice,reset之類的分布式服務中不可或缺的資料轉送對象DTO)模式,DTORequest/Response)就是一個很典型的資料載體,只存在簡單的get,set屬性,並且更傾向於作為值對象存在。而對象則剛好相反作為物件導向的產物,必須封裝隱藏資料,而暴露出行為介面,DDD中領域模型傾向於對象不僅在資料更多暴露行為操作自己或者關聯狀態。
雖然資料結構和對象之間看是細微的差別卻導致了不同的本質區別:使用資料結構的代碼便於在不改動現在資料結構的前提下添加新的行為函數),物件導向代碼則便於不改動現 有函數的前提下添加新的類。換句話說就是資料結構難以添加新的的資料類型,因為需要改動所有函數,物件導向的代碼則難以添加新的函數,因為需要修改所有的類。在任何一個複雜的系統都會同時存在資料結構和對象,我們需要判斷的是我們需要的是需要添加的新的資料類型還是新的行為函數。
在則就是迪米特法則,或被譯為最小知識原則,不和陌生人說話:模組不應該瞭解他所操作的對象的內部情形,關於對象的隱藏,更細緻的理解為一個對象A的方法f,應該也只能調用對象為下列範圍內:
方法不應和任何調用方法返回的對象操作,換句話之和朋友說話,不和陌生人說話。比如:ctxt.getOptions().getSearchDir().getAbsolutePath(),就是迪米特法則的反例模式。
但當前迪米特法則的前提是對象,如果是資料結構,沒有什麼行為,則他們自然會暴露其內部資料結構,迪米特法則也失效了。
隱藏作為物件導向主要特性中的最重要特性,封裝隱藏是物件導向中最重要的特性,一個好的物件導向代碼肯定是對對象的內部細節做到很好的隱藏封裝,封裝過後才有是多態,委派之類的。一個好的物件導向的代碼一定是具有很好的隱藏封裝,易於測試,不穩定因素往往集中在一處很小或者固定的位置,不穩定因素的變更不會導致更大面積的修改擴散。
最後推薦下一本書籍,值得在空閑時間看看,不能保證看完代碼就一定寫出整潔的代碼,做到童子軍軍規“每次簽入的代碼比簽出的更整潔”,更不會像優美的散文,這需要在項目實踐中不斷練習發現,但對代碼品質意思有著引導作用。
總感覺自己的技術還差得很遠,所以我總是約束自己抽出可用的時間看些書籍,從不同的視角,不同的領域或者一些思想的提升和沉澱。
關於物件導向原則隨筆還有: