2013年11月12日 星期二

Design Pattern - 6大設計原則

單一職責原則(Single Responsibility Principle)

  • 定義
    • There should never be more than one reason for a class to change
    • 應該有且僅有一個原因引起類別的變更
  • 好處
    • 類別的複雜性降低,實現什麼職責都有清晰明確的定義
    • 可讀性提升。複雜性降低,可讀性當然提升
    • 可維護性提升
    • 變更引起的風險降低

里氏替換原則

  • 繼承
    • 優點
      • 程式碼共享,減少創建類別的工作量,每個子類別都擁有父類別的方法和屬性
      • 提升程式碼的重用性
      • 子類別可以形似父類別,但又異於父類別
      • 提升程式碼的可擴展性
      • 提升產品或專案的開放性
    • 缺點
      • 繼承是侵入性的,只要繼承就必須擁有父類別的所有屬性和方法
      • 降低程式碼的靈活性。子類別必須擁有父類別的屬性和方法,讓子類別自由的世界多了些約束
      • 增強了耦和性。當父類別的常數、變數和方法被修改時,必需要考慮子類別的修改,而且在缺乏規範的環境下,這種修改可能會帶來非常糟糕的結果﹣大量的程式碼需要重構
  • 定義
    • If for eachobject p1 of type S there is an object o2 of type T such that for all programs P defined in terms of T, the behavior of P is unchanged when o1 is substituted for o2 then S is a subtype of T
      如果對每一個型別為S的物件o1,都有型別為T的物件o2,使得以T定義的所有程式P在所有的物件o1都替換成o2時,程式P的行為沒有發生變化,那麼型別S就是型別T的子型別
    • Functions that use pointers or references to base classes must be able to use objects of derived classes without knowing it
      所有參照基礎類別的地方必須能透明地使用其衍生類別的物件
  • 含義
    1. 子類別必須完全實作父類別的方法
    2. 子類別可以有自已的個性
    3. 覆寫或實作父類別的方法時輸入參數可以被放大
    4. 覆寫或實作父類別的方法時輸出結果可以被縮小

倚賴倒置原則(Dependence Inversion Principle,DIP)

  • 定義
    • High level modules should not depend upon low level modules. Both should depend upon abstractions. Abstractions should not depend upon details. Details should not depend upon abstractions.
    • 高層模組不應讓倚賴低層模組,兩者都應該倚賴其抽象
    • 抽象不應該倚賴細節
    • 細節應該倚賴抽象
  • 倚賴的三種寫法
    1. 構造函式傳遞倚賴物件
    2. Setter方法傳遞倚賴物件
    3. 介面聲明倚賴物件

物件導向基礎

以前看大話程式設計整理的物件導向基礎,現在剛好在重看就順便把它再整理一下囉~


物件(Object)

  • 一個獨立自主的實體,用一組可識別的特性和行為來標示

類別(Class)

  • 具有相同之屬性和功能的物件的抽象集合

實體(instance)

  • 一個真實的物件
  • 實體化就是建立建件的過程,使用new關鍵字來建立

建構式(constructor)

  • 又叫建構函式,其實就是對類別進行初始化。
  • 建構式與類別同名,無返回值
  • 所有類別都有建構式,若無定義,系統會自動產生空的建構式;若有定義,則預定的建構式就會失效

方法重載(Overload)

  • 提供建立同名的多個方法的能力,這些方法需使用不同的參數類型
  • Overload方法名相同,參數類型或個數要有所不同
  • Overload可在不改變原方法的基礎上,新增功能

屬性(Property)

  • 一個方法或一對方法,但在調用它的程式碼看來,它是一個欄位,即屬性適合於以欄位的方式使用方法調用的場合
  • 欄位是儲存類別要滿足其設計所需要的資料,欄位是與類別相關的變數
  • 屬性有二個方法get和set
    • get存取器返回與宣告的屬性相同的資料類型,調用時可以得到內部欄位的值或參考
    • set存取器沒有顯示設定參數,但它有一個隱式參數,用關鍵字value表示,它的作用是調用屬性時,可以給內部的欄位或參考賦值

封裝(Encapsulation)

  • 每個物件都包含它進行操作所需要的所有資訊,物件不必依賴其他物件來完成自已的操作
  • 好處
    • 良好的封裝能夠減少耦合
    • 類別內部的實現可以自由的修改
    • 類別具有清晰的對外介面

繼承(Inheritance)

  • 物件的繼承代表了一種“is-a"的關係
  • 繼承者可以理解為是對被繼承者的特殊化,它除了具備被繼承者的特性外,還具備自已獨有的個性
  • 繼承定義了類別如何相互關聯,共用特性
  • 父類別和子類別,或叫基礎類別和衍生類別,其中子類別繼承父類別的所有特性,還可以定義新的特性
    • 子類別擁有父類別非private的屬性和功能
    • 子類別具有自已的屬性和功能
    • 子類別還可以用自已的方式實現父類別的功能(方法重寫)
  • 優點
    • 繼承使得子類別公共的部分都放在父類別,使得程式碼得到共用,避免了重覆
    • 繼承可使得修改或擴展繼承而來的實現都較為容易
  • 缺點
    • 父類別變動,子類別也不得不變
    • 繼承會破壞包裝,父類別實現細節暴露給子類別
  • 繼承是一種類別與類別之間強耦合的關係
  • 當二類別之間具備“is-a"的關係時,就可以考慮用繼承

修飾子

  • Public
    • 所修飾的類別成員可以允許其他任何類別來存取
  • Protected
    • 子類別可對基礎類別有完全的存取權
  • Private
    • 只允許同一個類別中的成員存取

多型(Polymorphism)

  • 不同的物件可以執行相同的動作,但要透過它們自已的實現程式碼來執行
  • 特性
    • 子類別以父類別的身份出現
    • 子類別在工作時以 自已的方式來實現
    • 子類別以父類別的身份出現時,子類別特有的屬性和方法不可以使用
  • 子類別將父類別的實現替換為自已的實現,這就是方法重寫(Override),或者叫方法覆寫
  • 多型的原理是當方法被調用時,無論物件是否轉換為其父類別,都只有位於物件繼承的最末端的方法實現會被調用,也就是說,虛擬方法是按照其執行時類型,而非編譯時類型進行動態繫結調用