面向對象設計原則之開閉原則

開閉原則是面向對象的可複用設計的第一塊基石,它是最重要的面向對象設計原則。開閉原則由Bertrand  Meyer於1988年提出,其定義以下:java

開閉原則(Open-Closed Principle, OCP):一個軟件實體應當對擴展開放,對修改關閉。即軟件實體應儘可能在不修改原有代碼的狀況下進行擴展。編程

      在開閉原則的定義中,軟件實體能夠指一個軟件模塊、一個由多個類組成的局部結構或一個獨立的類框架

      任何軟件都須要面臨一個很重要的問題,即它們的需求會隨時間的推移而發生變化。當軟件系統須要面對新的需求時,咱們應該儘可能保證系統的設計框架是穩定的。若是一個軟件設計符合開閉原則,那麼能夠很是方便地對系統進行擴展,並且在擴展時無須修改現有代碼,使得軟件系統在擁有適應性和靈活性的同時具有較好的穩定性和延續性。隨着軟件規模愈來愈大,軟件壽命愈來愈長,軟件維護成本愈來愈高,設計知足開閉原則的軟件系統也變得愈來愈重要。編程語言

      爲了知足開閉原則,須要對系統進行抽象化設計,抽象化是開閉原則的關鍵。在Java、C#等編程語言中,能夠爲系統定義一個相對穩定的抽象層,而將不一樣的實現行爲移至具體的實現層中完成。在不少面向對象編程語言中都提供了接口、抽象類等機制,能夠經過它們定義系統的抽象層,再經過具體類來進行擴展。若是須要修改系統的行爲,無須對抽象層進行任何改動,只須要增長新的具體類來實現新的業務功能便可,實如今不修改已有代碼的基礎上擴展系統的功能,達到開閉原則的要求。編輯器

      Sunny軟件公司開發的CRM系統能夠顯示各類類型的圖表,如餅狀圖和柱狀圖等,爲了支持多種圖表顯示方式,原始設計方案如圖1所示:spa

圖1 初始設計方案結構圖.net

      在ChartDisplay類的display()方法中存在以下代碼片斷:設計

[java]  view plain  copy
 
  1. ......  
  2. if (type.equals("pie")) {  
  3.     PieChart chart = new PieChart();  
  4.     chart.display();  
  5. }  
  6. else if (type.equals("bar")) {  
  7.     BarChart chart = new BarChart();  
  8.     chart.display();  
  9. }  
  10. ......  

      在該代碼中,若是須要增長一個新的圖表類,如折線圖LineChart,則須要修改ChartDisplay類的display()方法的源代碼,增長新的判斷邏輯,違反了開閉原則。xml

      現對該系統進行重構,使之符合開閉原則。對象

       在本實例中,因爲在ChartDisplay類的display()方法中針對每個圖表類編程,所以增長新的圖表類不得不修改源代碼。能夠經過抽象化的方式對系統進行重構,使之增長新的圖表類時無須修改源代碼,知足開閉原則。具體作法以下:

      (1) 增長一個抽象圖表類AbstractChart,將各類具體圖表類做爲其子類;

      (2)  ChartDisplay類針對抽象圖表類進行編程,由客戶端來決定使用哪一種具體圖表。

      重構後結構如圖2所示:

圖2 重構後的結構圖

      在圖2中,咱們引入了抽象圖表類AbstractChart,且ChartDisplay針對抽象圖表類進行編程,並經過setChart()方法由客戶端來設置實例化的具體圖表對象,在ChartDisplay的display()方法中調用chart對象的display()方法顯示圖表。若是須要增長一種新的圖表,如折線圖LineChart,只須要將LineChart也做爲AbstractChart的子類,在客戶端向ChartDisplay中注入一個LineChart對象便可,無須修改現有類庫的源代碼。     

       注意:由於xml和properties等格式的配置文件是純文本文件,能夠直接經過VI編輯器或記事本進行編輯,且無須編譯,所以在軟件開發中,通常不把對配置文件的修改認爲是對系統源代碼的修改。若是一個系統在擴展時只涉及到修改配置文件,而原有的Java代碼或C#代碼沒有作任何修改,該系統便可認爲是一個符合開閉原則的系統。

相關文章
相關標籤/搜索