« Open for Extension, Closed for Modification | 網頁 | 有趣的 GTD TiddlyWiki »
06/05/2005
Open for Extension, Closed for Modification
除了 Design Patterns 之外,近年來物件導向設計領域還開始講究 OO principle. 像是從前年開始流行起來的 micro kernel framework -- PicoContainer 及 Spring Framework 所講究的 dependency inversion,本身也是一種 principle。而 RMI, EJB 及 Jini 等遠端物件技術,則符合另一 principle -- Program to an interface, not an implementation. 這些 principle 之所以存在,最主要的目的就是讓我們在設計系統時,可以增加系統的擴充性與維護性。對這些 principle 有與趣者,可以到 Object Mentor 尋找相關資料。
由於昨天部門讀書會剛好討論到這個議題,我便就這個主題發表一下我的看法。像是這個讓人覺得矛盾的 Open Closed Principle, 也就是 Open for Extension, Closed for Modification,到底 Open (開放)了什麼東西,Closed (禁制)了什麼東西。用簡單的話來講,這項原則強調:
* 在設計一類別時,應保留足夠的彈性,讓採用此類別的程式,透過擴充的手法,即可新增或變更系統功能。
* 在設計一類別時,應具有適當的封閉性,避免讓採用者直接修改類別原始程式,才可達成其功能。
我想寫過稍大一點程式的朋友一定會這種經驗,當我們在程式中採用一個類別時,有時候發現該類別少了許多我們所要的特性或功能,這時候我們可能採取以下幾種作法,來達到呼叫者所要的功能:
* 你可能動手直接修改該類別某個 method 的實作
* 你可能在該類別中新增你所須要的 method
* 你可能透過建立一個該類別的子類別,再採用其子類別,來達到你所需要的功能
* 你可能將該類別的某些職責(responsibilities),透過 composition 或 delegation,交給別的物件處理,就可以達到你所需要的功能
究竟採取何種作法,除了視採用者個人的偏好外,還與原始類別設計的好壞有關。各位可以看到,上面的這幾種方法中,越上面的方法,對你原本系統的程式修改越多,而越下面的方法,對原程式的修改越少。因此如果一個類別的設計,能讓採用者越喜好使用下面的方法來達成其功能,則原始類別的設計,就越符合 Open Closed Principle。
我再舉一個 JDK 的例子,在我們使用 JDK 裡面的 API 時,就不太可能會想要動手去修改 API 裡面的實作。例如:當你發現 JButton 少了你所需要的屬性時,你大概不會動手修改 JButton 的原始碼;反之,你可能會新建一個 JButton 的子類別,再於其中加入自己所需的屬性,這就符合了Open Closed Principle (甚至所有的 JComponent 都允許你用 putProperty 的方式,在不用新建子類別的方式之下,動態新增屬性)。還有不少 JDK API 的設計,也都符合這項原則,像是 sort 只要傳入 Comparable,JButton 有 addActionLisenter, JTable 有 TableModel... 不勝枚舉。
07:30 發表於 Developing | 永久網址 | 留言 (0) | Email this | Tags: Programming, software, design, oo, object, oriented


