學習面向對象的設計原則

現在是OO語言流行的時代,但是我們真的能深入運用OO的特性來進行軟件開發,或是在開發一套純的軟件系統嗎?我想絕大部分人不敢站出來肯定自己所參與開發的是一套純正的具有OO血統的系統!(不過,技術是爲需求而用,有些地方可能確實一時之間難以利用OO思維去思考)。

但無論如何,我們如今的軟件開發都強調OO,那麼,作爲OO基礎的知識,我們真的能掌握了嗎?其實掌握了的人,在現實的軟件開發中,還是不能第一時間用OO考慮如何解決問題?可能都是我們作爲程序員的思維一定侷限吧,既是用一般的面向過程去考慮如何解決一個問題(或需求)。還記得從《設計模式解析》這本書上,作者提到,我們應該學會用模式去思考!這個不得不引起我們的沉思!我想我們作爲一名程序員,不能過於浮躁,但現今的社會又有哪個能做到呢?算了吧,還是看看我們OOD中的最基本的原則吧!好好學習一番,算是給自己複習,淨化自己的浮躁的心!

【引】在面向對象設計中,如何通過很小的設計改變就可以應對設計需求的變化,這是令設計者極爲關注的問題。爲此不少OO先驅提出了很多有關面向對象的設計原則用於指導OO的設計和開發。當然,在此,我們更不可忘掉OO中的三大特性吧,抽象、封裝、多態。《Leaning Design Patterns by Looking at code》的作者就說過,85%的軟件開發都是面向接口(即面向抽象)、多態編程!

  1. 我們先來看看在面向對象中有哪些設計原則,follow:

    關於類設計的


    • OCP開放封閉原則 (Open Close Principle),軟件實體(類、模塊、函數)在擴展性方面應該是開放的而在更改性方面應該是封閉的。在進行面向對象設計時要儘量考慮接口封裝機制、抽象機制和多態技術。該原則同樣適合於非面向對象設計的方法,是軟件工程 設計方法的重要原則之一。
    • 通過一些例子來描述吧
    • 這是一個違背了OCP原則的例子,每當我們要添加一個圖形的時候,都要修改代碼,影響到已存在的功能。
      Open Close Principle(OCP) - bad
  • // Open-Close Principle - Bad example
  • class GraphicEditor {
    •     public void drawShape(Shape s) {
  •          if (s.m_type==1)
  •              drawRectangle(s);
  •         else if (s.m_type==2)
  •             drawCircle(s);
  •       }
  •       public void drawCircle(Circle r) {....}
  •       public void drawRectangle(Rectangle r) {....}
  • }
  • class Shape {
  •      int m_type;
  • }
  • class Rectangle extends Shape {
  •          Rectangle() {
  •                  super.m_type=1;
  •          }
  • }
  • class Circle extends Shape {
  •          Circle() {
  •          super.m_type=2;
  •           }
  • }

上面的幾個缺點:
每增加一個圖形,對於GraphicEditor都要重做一次單元測試
當一個新圖形被添加時,都要求開發人員理解GraphicEditor裏面的程序邏輯
添加一個新圖形在我們不期望的方式來影響程序現有的缺點,即使新添的圖形能運行良好。

看用OCP原則來重新設計上面的例子

Open Close Principle(OCP) - good

// Open-Close Principle - Good example
class GraphicEditor {
public void drawShape(Shape s) {
s.draw();
}
}

class Shape {
abstract void draw();
}

class Rectangle extends Shape {
public void draw() {
// draw the rectangle
}
}

  1. SRP單一職責原則 (Single Responsiblity Principle),就一個類而言,應該僅有一個引起它變化的理由。
  2. LSPLiskov替換原則 ,子類應當可以替換父類並出現在父類能夠出現的任何地方。
  3. DIP依賴倒置原則 (Dependency Inversion Principle),依賴關係應該儘量依賴接口與抽象類(即是依賴抽象),而不是依賴於具體類。
  4. ISP接口隔離原則 (Interface Segregation Principle),採用多個與特定客戶類有關的接口比採用一個通用的涵蓋多個業務方法的接口要好。

    對於另外六項原則,則都是關於包的設計原則。在這裏,包是指一個二進制的可發佈文件,如Jar文件、DLL文件等。不等同於Java語言中的package或C++的命名空間之類

關於包內聚性的:

  • REP,重用發佈等價原則 ,重用的粒度就是發佈的粒度。
  • CPP,共同封閉原則 ,包中的所有類對於同一類性質的變化應該是共同封閉的。
  • CRP,共同重用原則 ,一個包中的所有類應該是共同重用的。

關於包之間的耦合性原則的:

  • ADP,無環依賴原則,在包的依賴關係圖中不允許存在環。
  • SDP,穩定依賴原則,朝着穩定的方向進行依賴。
  • SAP,穩定抽象原則,包的抽象程度應該和其穩定程度一致。

在以上的OOD原則中,開發中常見的應該是前面介紹到關於類設計的幾個原則。在進行面向對象的軟件開發過程中,當然,我們不可能時刻把這些原則掛在嘴邊,重要的是時刻惦記着儘可能使用在開發過程中。但是,我們應該要時刻審視我們自己的代碼是否符合基本的原則,在軟件開發中,最重要的還是如何去建立“鬆耦合”。

代碼和圖片來源自【http://www.oodesign.com/ 】,還有其他的內容來自互聯網,總之,感謝分享知識的人們!

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章