前言 國際慣例,本文寫於本人使用《大話設計模式》一書學習設計模式的路上,適用於初學設計模式的道友交流之用,大神誤入,請留下您寶貴的意見,感激不盡; 開閉原則 定義 軟體實體應當對擴展開放,對修改關閉; 特征 1. 對擴展開放:當需要添加新的功能,或者說擴展功能時,我們不需要修改原來的代碼,只需要添加 ...
前言
國際慣例,本文寫於本人使用《大話設計模式》一書學習設計模式的路上,適用於初學設計模式的道友交流之用,大神誤入,請留下您寶貴的意見,感激不盡;
開閉原則
定義
軟體實體應當對擴展開放,對修改關閉;
特征
對擴展開放:當需要添加新的功能,或者說擴展功能時,我們不需要修改原來的代碼,只需要添加新的類就可以滿足需求;
對修改關閉:對功能進行擴展時,不需要修改原有代碼的源代碼後者二進位代碼(只修改配置文件,並不算違背開閉原則);
理解
在軟體的整個生命周期中,從需求的變更到系統的升級以及後期的維護,不可避免的要對原有的代碼進行重構,並且需要原有的代碼的測試結果與新的代碼的測試結果的對比,如果直接在原有代碼上修改,那麼就需要對原有代碼進行備份,等到新的代碼修改完成後運行比對,這樣做也未嘗不可,但是如果系統的部署比較複雜,或者說你要修改線上的代碼,這時候就比較困難了,那麼這時候怎麼辦呢?這就需要用到我們這裡所說的開閉原則;
那麼什麼是開閉原則呢?簡單來說就是對修改關閉,對擴展開放,那麼怎麼才能做到對修改關閉,對擴展開放呢?需要做到以下幾點:
1.儘量不修改原來的代碼:除非是修改原來代碼中的錯誤,否則儘量不要去修改原來的代碼,但是也有例外,比如擴展了底層模塊,高層模塊還是需要發生一些變化的,不然低層模塊的擴展就是沒有任何意義的代碼片段;
2.以抽象代替實現:這也是我們一直所說的面向介面編程,當然這裡的抽象並不僅僅是指介面,還可以是抽象類(本人是搞java的,所以特指java,別的語言請選擇性參考);
3.以抽象隔離變化:首先,無論模塊是多麼的“封閉”,都會存在一些無法對之封閉的變化,既然不可能完全封閉,那麼設計人員必須對於其他設計的模塊應該對哪種變化封閉進行選擇,他必須猜測出最有可能發生的變化種類,然後構造抽象來隔離變化,其次,我們並沒有未卜先知的能力,所以在最初編寫代碼時可以假設變化不會發生,但是當變化發生時,我們就需要去創建抽象來隔離以後發生的同類的變化;
4.抽象層設計到整個項目的架構,因此抽象層需要儘量保持穩定,一旦確定就不要輕易修改;
5.避免不合理的抽象:開閉原則需要使用抽象,但是過度的抽象或者說不合理的抽象同樣會帶來很大的問題,因此抽象應該做到合理的抽象;
其他設計原則是實現開閉原則的一種手段:其中單一原則要求做到類的職責單一,里式提花原則要求不能破壞繼承體系,依賴倒置原則要求我們要面向介面編程,介面隔離原則要求做到介面要精簡單一,迪米特法則則是要求做到降低耦合度,如果遵循了前面的五個法則,那麼自然的也就做到了開閉原則,因此說開閉原則是設計原則的總綱(參考文章)
優點
- 可復用行好:軟體系統完成之後,仍然可以對軟體進行擴展,理想狀態下可以做到無限擴展,通過擴展加入新的功能,十分靈活;
- 可維護性好:抽象層是固定的,因此在修改在進行擴展時不需要去考慮原有組件的穩定性,只需要實現或者繼承現有抽象層既可以做到擴展新的功能,這就使變化中的軟體系統具有一定的穩定性和延續性;
參考文章
- http://blog.csdn.net/zhengzhb/article/details/7296944
- http://blog.csdn.net/lovelion/article/details/7537584
- http://www.cnblogs.com/muzongyan/archive/2010/08/05/1793454.html
- 百度百科