[IT 男人幫 11-07] 你以爲你瞭解面向對象設計麼?

 

來自: http://www.cnblogs.com/wanghui9072229/archive/2011/05/10/2042541.html

你以爲你瞭解面向對象設計麼?你可能說:“是的,我瞭解!”那麼好,來看一個例子。


下面這個設計,你認爲是面向對象設計麼?


Button類的代碼如下:

public class Button { private Lamp lamp; public void Poll() { if (/* some condition*/) { lamp.TurnOn(); } } }


你可能會說,這個設計用到了封裝、繼承和多態,這難道不是面向對象的三大機制麼?


那麼好,你的回答說明你已經很瞭解面向對象的基礎知識了。但是這就是面向對象設計了麼?


百度百科裏關於面向對象設計是這麼定義的:“面向對象設計模式是‘好的面向對象設計’。”剛開始看到這句話,我懷疑這句話是不是有語病。其實,它的言外之意是:差的面向對象設計不是面向對象設計,所謂“好的面向對象設計”是那些可以滿足“應對變化,提高複用”的設計。


上面這個設計嚴格的說,有不好的、或不成熟的地方。主要是Button依賴Lamp類,這主要會有2個問題,一是Lamp改變,Button類會受影響,即所謂的僵化性。二是想要重用Button類去控制其它的東西是不可能的,即所謂的頑固性。這個例子是《敏捷軟件開發——原則、模式與實踐(C#版)》一書“DIP:依賴倒置原則”一章中的例子,筆者稍加修改。


運用依賴倒置原則把Button和Lamp的關係改進後的設計是這樣的(見下)。


至於依賴倒置原則,說的已經太多了,不是本文重點,略過。但Bob大叔的一段話,還是很值得琢磨的。


“事實上,這種依賴關係的倒置正是好的面向對象設計的標誌所在。使用何種語言來編寫程序是無關緊要的。如果程序的依賴關係是倒置的,它就是面向對象的設計。如果程序的依賴關係不是倒置的,它就是過程化的設計。”


之所以寫這篇隨筆,是因爲最近看另一篇關於面向對象的博客“我們需要養成面向對象的編程習慣”及其評論時感到,有些朋友把面向對象設計和非面向對象設計的對比等同於面向對象編程語言(OOPL)和非面向對象編程語言的對比。


引用百度百科“面向對象設計”詞條中的一些話來闡述一下:


通過面向對象編程語言(OOPL)認識到的面向對象,並不是面向對象的全部,甚至只是淺陋的面向對象。


OOPL的三大機制“封裝、繼承、多態”可以表達面向對象的所有概念,但這三大機制本身並沒有刻畫出面向對象的核心精神。換言之,既可以用這三大機制做出“好的面向對象設計”,也可以用這三大機制做出“差的面向對象設計”。不是使用了面向對象的語言(例如C#),就實現了面向對象的設計與開發!因此我們不能依賴編程語言的面向對象機制,來掌握面向對象。


本來可以結束本文了,但是考慮到有些朋友可能會置疑前文中的一點,所以再補補漏。


有些朋友可能會認爲,如果Button和Lamp一旦設計好後就不會再變化,那麼最前面的設計可能就是一個好的設計了,而後面的設計反倒有不必要的複雜性,或者說是《重構》中所說的“誇誇其談未來性Speculative Generality”。


還有朋友可能說,敏捷的設計是用增量的方式來完成的,敏捷的技術實踐TDD、重構都是主張先做足夠用的設計,然後小步持續改進。所以最前面的設計如果是夠用的,那麼就沒有必要一開始就把它弄複雜。


以上說法,本人也很贊同。本來世界上絕對的東西就很少,尤其技術領域。畢竟,我們智慧的價值,就在於能尋找預見性和適應性的最佳平衡點,這不是機器能做到的。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章