2013年1月29日 星期二

Design Pattern

最近小弱弱版主在看設計模式(design pattern)相關的書,寫一下我對它的感想。

我認為design pattern中相當重要的是繼承和polymorphism的概念:
繼承讓我們能定義一個基礎的型別,然後依據不同類型的物件,都繼承自這個基礎型別
Polymorphism則允許我們利用基礎型別的pointer,依據執行時指向的物件來取用它的資料。

從design pattern來看,Polymorphism有兩個最重要的功能:
1. 也就是上面提過的,是在執行期決定要執行哪個function,只要用父代的pointer去access繼承產生的子代,就可以視生成哪個物件來取用它的function,這也是一般教polymorphism時會提到最基本的用處,相信設計師都很清楚了。
2. 第二個功能延伸自第一個,利用polymorphism給予我們執行期時的彈性,延伸出來的是,在設計、修改時保有彈性(也就是Design Pattern),把每個不相干的部分給分開,讓我們不必要每次要新增功能、新增新的物件時,都要進到Implementation的層次做修改,浪費許多時間在尋找該加上新功能的地方;另外也能減少增加新東西時,因為相依關係而要重新編譯的部分。
事實上我認為第二個功能的重要性遠高於第一項,設計的彈性增進工作效率,才能將Object oriented的火力全面發揮出來。

說個自己想,沒什麼用的例子:
比如說我們要寫個選角色的程式好了,每個角色都有一個主要的招式master spark之類
所以說,最簡單的寫法就先設定一個基礎的角色:class character,內含一個main_spell()
然後各個角色繼承這個character.h,定義自己的main_spell()裡面要幹什麼,這時候所有角色的介面就一致了,可以用一個character的pointer來操作每一個角色的功能。
但這樣做其實不夠好,如果今天我們希望有些角色的main_spell不要動作怎麼辦?然後每個人招式又都不一樣?
我們可以打開每個角色的原始碼,然後重載(overload, 這個翻譯=w=)main_spell()
可是如果我們要加上10個角色呢?
所以Design Pattern就會要求,不止character,連main_spell也要是一個base class,不同的招式則是繼承它後修改,character則包含一個main_spell的pointer,用polymorphism的方式取得不同招式;如此一來,可以很方便的加上新的main_spell,只要新增main_spell的class即可,在character的介面卻完全不需要更動, 在維護跟更新上會更有效率。

這個composition over inheritance應該算是最基本的design pattern的概念了,Design Pattern所教的,就是過去神級的設計師,針對許多設計上的問題提出適當的解決方案(雖然感覺就是愈會變動的地方就會加上更多虛擬層,或是愈切愈細),據說在STL裡面用上許多Design Pattern,如果小弱弱板主學有心得再上來獻醜。

參考資料:
1. Head First Design Pattern:
http://shop.oreilly.com/product/9780596007126.do
會用google的可以在後面加上pdf
2. http://sourcemaking.com/design_patterns
包山包海的Java/C++ source code