Agile Principles, Patterns, and Practices in C# 無瑕的程式碼 敏捷完整篇 第9章 OCP:開放─封閉原則
第九章內容是OCP:開放─封閉原則,第一次看到這個名詞會覺得「二律背反」的感覺,只要看懂一個範例就能了解OCP的意義。
OCP(The Open-Closed Principle): 開放─封閉原則
軟體實體(類別、模組、函式)應該是可擴展的,但不可修改。
正確應用OCP,就只需要增加新的程式碼,不必修改舊有的程式碼。
OCP概述
對於擴展是開放的(open for extension)
需求改變的時候,可對模組進行擴展,改變模組的功能。
對於修改是封閉的 ( closed for modification)
對模組行為進行擴展時,不必更動舊有的程式碼。程式庫、DLL與EXE都不需要改變。
如何做到OCP? 抽象 (abstraction)
圖9-1是不遵守OCP的簡單設計,當Client使用不同的伺服器物件,就必須改Client類別中所有Server類別。
圖9-2遵循OCP來做設計STRATEGY策略模式,新增Client Interface介面,更換Server只需要從Client Interface介面衍生出一個新的類別,無需對Client類別做任何更動。
抽象類別和他們的客戶關係要比實作他們的類別的關係更密切一些,所以抽象介面命名為ClientInterface,而不是AbstractServer 。
圖9-3使用TEMPLATE METHOD 樣版方法模式(??????)做到OCP
Shape 應用程式
這段內容直接看程式 Listing 9-1 比較快,原有的程式用C語言撰寫,圓形與方形放在list 陣列之中畫出來。假設要新增三角形,會變得要全部翻修找出switch語句修改,然後重新編譯。這段程式違反OCP原則。
Listing 9-2 符合OCP解決方案。建立一個Shape介面,其他形狀繼承這個介面,即使新增三角形形狀也不會影響其他程式碼部分。
作者提到若是使用工廠模式產生物件情況又會有所不同。
如果遇到新的變化是「圓形必須畫在方形之前」,抽象與多形的方法就會「破功」。
預測變化和「貼切的」結構
作者指出根本不存在對於所有情況都貼切的模型,既然「計畫敢不上變化」,最終我們會一直等到變化發生時再行動。
放置鉤子
有一種方法「放置鉤子」是預先猜測會有變化的地方,作者反對這種作法,認為反而會增加軟體的複雜性。
只被愚弄一次
程式第一版的時候都假設變化不會發生,出現變化之後再進行調整。
刺激變化
遇到變化越早,對寫程式越有利。作者提供一些方法讓變化提早發生
測試驅動開發(TDD)
儘快完成程式
請益利益相關者(客戶或是客服人員)
程式先寫最重要的部分
盡可能頻繁地把軟體展示給客戶或使用者
使用抽象獲得顯示封閉
針對「圓形必須畫在方形之前」的變化,作者利用 C#提供的IComparable介面,在畫圖之前List先進行排序,參考Listing9-3 、Listing9-4 與Listing9-5 。
然而這種作法遇到「新增三角形」的情況又會「破功」所有的CompareTo函數都要修改,不符合OCP 。
使用「資料驅動」的方式獲取封閉性
Listing 9-6 作者利用HashTable事先定義形狀的先後次序,讓程式面對兩種變化「新增三角形」與「圓形必須畫在方形之前」
程式???????
總結
物件導向設計的核心之一就是OCP。
開發人員僅對頻繁變化的部分做出抽象。
拒絕不成熟的抽象和抽象本身一樣重要。
留言
張貼留言