天天看點

設計原則之開閉原則

定義:一個軟體實體(類、子產品或函數)應當對擴充開放,對修改關閉。
   也就是說軟體實體應盡量在不修改原有代碼的情況下進行擴充。

問題:在軟體的生命周期内,因為變化、更新和維護等原因需要對軟體原有代碼進行修改時,可能會給舊代碼中引入錯誤,
   也可能會使我們不得不對整個功能進行重構,并且需要重新測試。

方案:當軟體需要變化時,盡量通過擴充軟體實體的行為來實作變化,而不是通過修改已有的代碼來實作變化。

舉個栗子:這是一個包工頭和勞工的故事。。。

情況一:包工頭給勞工命名編号。具體實作方式如下:

1. 建立一個勞工接口IWorker,包含一個勞工編号的方法。代碼如下:      
設計原則之開閉原則
2. 建立一個勞工類Worker,來實作上面的IWorker接口方法。代碼如下:      
設計原則之開閉原則
3. 建立一個包工頭類Manager,包含一個給勞工命名編号的方法,依賴IWorker接口。代碼如下:      
設計原則之開閉原則
4. 在類OCPFragment中使用Worker對象調用命名編号的方法來實作功能。代碼如下:      
設計原則之開閉原則
5. 運作後的效果,如下:      
設計原則之開閉原則
  以上的實作方式,成功完成了給勞工命名編号的方法。現在我們要新增一個給勞工配置設定角色和任務的功能,如果在現有代碼的基礎上作修改的話,比如在IWorker接口新增勞工角色role()和勞工任務doing()兩個方法,在勞工類Worker中去實作,修改包工頭類Manager中的nameWorker()方法,這樣做,如果多處調用了nameWorker()方法的話,很可能會造成原有功能發生故障,是以這時我們必須遵守開閉原則,對修改關閉、對擴充開發,不去修改原有的nameWorker()方法,而是去新增一個專門用于給勞工配置設定角色和任務的方法,這樣不僅不會影響到原有的功能,還提高了代碼的複用性,更加靈活。

情況二:包工頭給勞工命名編号,給勞工配置設定角色和任務。遵守開閉原則,具體實作方式如下:

1. 在IWorker接口中新增勞工角色role()和勞工任務doing()兩個方法。代碼如下:      
設計原則之開閉原則
2. 勞工類Worker需要去實作新增的兩個方法。代碼如下:      
設計原則之開閉原則
3. 在包工頭類Manager中新增一個給勞工配置設定角色和任務的方法,依然依賴IWorker接口。代碼如下:      
設計原則之開閉原則
4. 在類OCPFragment中仍使用Worker對象去調用allocateTask()方法來實作功能。代碼如下:      
設計原則之開閉原則
5. 運作後的效果,如下:      
設計原則之開閉原則
  綜上所述,如果一個軟體系統符合開閉原則,那麼從軟體工程的角度來看,它将具有可複用性好和可維護性好兩大特點。開閉原則是面向對象設計中“可複用設計”的基石,是面向對象設計中最重要的原則之一。

原則:
     1. 通過接口或抽象類限制擴充,對擴充進行邊界限定;
     2. 參數類型、引用對象盡量使用接口或者抽象類,而不是實作類;
     3. 抽象層盡量保持穩定,一旦确定就不允許修改;
     4. 将相同的變化封裝在一個接口或抽象類中;
     5. 将不同的變化封裝到不同的接口或抽象類中。

總結:
     1. 單一職責原則要求實作類要職責單一;
     2. 裡氏替換原則要求不要去破壞繼承系統;
     3. 依賴倒置原則要求面向接口程式設計;
     4. 接口隔離原則要求在設計接口的時候要精簡單一;
     5. 迪米特法則要求要降低耦合;
     6. 開閉原則是總綱,要求對擴充開發,對修改關閉。      

轉載于:https://www.cnblogs.com/chenxkang/p/6669382.html