設計模式(0)—— 概述

設計模式(Design Pattern),是一套被反覆使用、多數人知曉的、經過分類編目的、代碼設計經驗的總結。

使用設計模式是爲了可重用代碼、讓代碼更容易被他人理解、保證代碼可靠性。 設計模式於己、於他人、於系統都是多贏的,設計模式使代碼編制真正工程化。設計模式是軟件工程的基石,如同大廈的一塊塊磚石一樣使代碼編制真正工程化。

只有精通了設計模式,纔敢說真正理解了軟件工程。可以說,設計模式是每一個架構師所必備的技能之一。作爲一個面向對象設計程序員,只有精通了設計模式,才能擺脫碼奴的命運,成爲一個真正的軟件工程師,才能完成自身價值的飛躍和設計思想的昇華!



1、設計模式和框架

  可複用面向對象軟件系統現在一般劃分爲兩大類:應用程序工具箱和框架(Framework),我們平時開發的具體軟件都是應用程序,Java的API屬於工具箱;而框架是構成一類特定軟件可複用設計的一組相互協作的類,EJB(Enterprise Java Beans)是Java應用於企業計算的框架。

  框架通常定義了應用體系的整體結構類和對象的關係等等設計參數,以便於具體應用實現者能集中精力於應用本身的特定細節。框架主要記錄軟件應用中共同的設計決策,框架強調設計複用,因此框架設計中必然要使用設計模式。
  另外,設計模式有助於對框架結構的理解,成熟的框架通常使用了多種設計模式,如果你熟悉這些設計模式,毫無疑問,你將迅速掌握框架的結構,我們一般開發者如果突然接觸EJBJ2EE等框架,會覺得特別難學,難掌握,那麼轉而先掌握設計模式,無疑是給了你剖析EJB或J2EE系統的一把利器。



2、設計模式的原則

近年來,大家都開始注意設計模式。那麼,到底我們爲什麼要用設計模式呢?爲什麼要提倡設計模式呢?

根本原因是爲了擺脫編程低效率,提高代碼複用,增強代碼健壯穩定,增加可維護性。


那怎麼才能實現代碼複用呢?

從面向過程到面向對象,是軟件設計誕生以來的邁出的最偉大的一步,面向對象程序設計成功解決了面向過程軟件編程的低效率問題,並且徹底改變了人們的編程思維,爲軟件設計揭開了新的篇章。然而,要實現面向對象設計,徹底擺脫面向過程設計思維,並不僅僅是隻要使用了一門面向對象的編程語言就能夠達到的。使用面向對象設計,可以設計出優秀的軟件,同樣也可以設計出糟糕的軟件。只有遵循一些特定的原則,才能設計出複用性高靈活性好的軟件來。

在運用面向對象的思想進行軟件設計時,需要遵循的原則一共有 6 條:

  1. 單一職責原則(Single Responsibility Principle)
  2. 里氏替換原則(Liskov Substitution Principle)
  3. 依賴倒置原則(Dependence Inversion Principle)
  4. 接口隔離原則(Interface Segregation Principle)
  5. 迪米特法則(Law Of Demeter)
  6. 開閉原則(Open Close Principle)

        在軟件設計的過程中,只要我們儘量遵循以上六條設計原則,設計出來的軟件纔會是一個優秀的軟件,它必定足夠健壯、足夠穩定,並以極大的靈活性來迎接隨時而來的需求變更等因素。



3、設計模式的四要素

  設計模式使人們可以更加簡單方便地複用成功的設計和體系結構。將已證實的技術表述成設計模式也會使新系統開發者更加容易理解其設計思路。

  • 模式名稱(pattern name)
  一個助記名,它用一兩個詞來描述模式的問題、解決方案和效果。命名一個新的模式增加了我們的設計詞彙。設計模式允許我們在較高的抽象層次上進行設計。基於一個模式詞彙表,我們自己以及同事之間就可以討論模式並在編寫文檔時使用它們。模式名可以幫助我們思考,便於我們與其他人交流設計思想及設計結果。找到恰當的模式名也是我們設計模式編目工作的難點之一。

  • 問題(problem)
  描述了應該在何時使用模式。它解釋了設計問題和問題存在的前因後果,它可能描述了特定的設計問題,如怎樣用對象表示算法等。也可能描述了導致不靈活設計的類或對象結構。有時候,問題部分會包括使用模式必須滿足的一系列先決條件。

  • 解決方案(solution)
  描述了設計的組成成分,它們之間的相互關係及各自的職責和協作方式。因爲模式就像一個模板,可應用於多種不同場合,所以解決方案並不描述一個特定而具體的設計或實現,而是提供設計問題的抽象描述和怎樣用一個具有一般意義的元素組合(類或對象組合)來解決這個問題。

  • 效果(consequences)
  描述了模式應用的效果及使用模式應權衡的問題。儘管我們描述設計決策時,並不總提到模式效果,但它們對於評價設計選擇和理解使用模式的代價及好處具有重要意義。軟件效果大多關注對時間和空間的衡量,它們也表述了語言和實現問題。因爲複用是面向對象設計的要素之一,所以模式效果包括它對系統的靈活性、擴充性或可移植性的影響,顯式地列出這些效果對理解和評價這些模式很有幫助。



4、設計模式分類概覽

《設計模式》一書,第 1 次將設計模式提升到理論高度,並將之規範化。書中一共總結了23種基本的設計模式,《設計模式》下載

這23種設計模式,幾乎涵蓋了面向對象設計過程中所有問題的解決方案,書中提到的23種設計模式分別是:

設計模式

(Design Pattern)

創建型

(Creational)

結構型

(Structural)

行爲型

(Behavioral)

1、Abstract Factory(抽象工廠)

2、Builder(建造者)

3、Factory Method(工廠方法)

4、Prototype(原型)

5、Singleton(單態)

 

 

 

 

 

 

 

6、Adapter(適配器)

7、Bridge(橋模式)

8、Composite(組合)

9、Decorator(裝飾)

10、Façade(外觀)

11、Flyweight(享元)

12、Proxy(代理)

13、Chain of Responsibility(職責鏈)

14、Command(命令)

15、Interpreter(解釋器)

16、Iterator(迭代器)

17、Mediator(中介)

18、Memento(備忘錄)

19、Observer(觀察者)

20、State(狀態)

21、Strategy(策略)

22、Template Method(模板方法)

23、Visitor(訪問者)



5、設計模式的設計場景

那麼如此多的設計模式又是從何而來呢?

《易經》有云:“易有太極,是生兩儀,兩儀生四象,四象生八卦”,意思就是說世界萬物皆有起源。

設計模式的起源,是面向對象程序設計思想,是面向對象設計的精髓——抽象。面向對象通過類和對象來實現抽象,實現時產生了面向對象的三個重要機制:封裝、繼承、多態,正是這三個機制衍生出了各種各樣的設計模式。

設計模式的支持設計

目的

設計模式

可變方面

創建

(Creational)

1、Abstract Factory

2、Builder

3、Factory Method

4、Prototype

5、Singleton

產品對象家族

如何創建一個組合對象

被實例化的子類

被實例化的類

一個類的唯一實例

結構

(Structural)

6、Adapter

7、Bridge

8、Composite

9、Decorator

10、Façade

11、Flyweight

12、Proxy

對象的接口

對象的實現

一個對象的結構和組成

對象的職責,不生成子類

一個子系統的接口

對象的存儲開銷

如何訪問一個對象,該對象的位置

行爲

(Behavioral)

13、Chain of Responsibility

14、Command

15、Interpreter

16、Iterator

17、Mediator

18、Memento

19、Observer

20、State

21、Strategy

22、Template Method

23、Visitor

滿足一個請求的對象

何時、怎樣滿足一個請求

一個語言的文法和解釋

如何遍歷、訪問一個聚合的各元素

對象間如何交互、與誰交互

一個對象中哪些私有信息存放在該對象之外,以及在什麼時候進行存儲

多個對象依賴於另外一個對象,而這些對象又如何保持一致

對象的狀態

算法設計

算法中的某些步驟

某些可作用於一個(組)對象上的操作,但不修改這些對象的類



6、設計模式的分類描述

設計模式分爲創建型模式、結構型模式、行爲型模式

設計模式的分類描述

創建型模式

1.抽象工廠模式

爲一個產品族提供了統一的創建接口。當需要這個產品族的某一系列的時候,可以從抽象工廠中選出相應的系列創建一個具體的工廠類。

2.建造者模式

將一個複雜對象的構建與它的表示分離,使得同樣的構建過程可以創建不同的表示。

3.工廠方法模式

定義一個接口用於創建對象,但是讓子類決定初始化哪個類。工廠方法把一個類的初始化下放到子類。

4.原型模式

用原型實例指定創建對象的種類,並且通過拷貝這些原型創建新的對象。

5.單例模式

確保一個類只有一個實例,並提供對該實例的全局訪問。

5.多例模式

確保一個類只有命名的實例,並提供對這些實例的全局訪問。

對象池模式

通過回收利用對象避免獲取和釋放資源所需的昂貴成本。

惰性初始模式

推遲對象的創建、數據的計算等需要耗費較多資源的操作,只有在第一次訪問的時候才執行。

資源獲取爲初始化

通過綁定到合適對象的生命週期來確保資源被適當地釋放。

結構型模式

6.適配器模式

將某個類的接口轉換成客戶端期望的另一個接口表示。適配器模式可以消除由於接口不匹配所造成的類兼容性問題。

7.橋接模式

將一個抽象與實現解耦,以便兩者可以獨立的變化。

8.組合模式

把多個對象組成樹狀結構來表示局部與整體,這樣用戶可以一樣的對待單個對象和對象的組合。

9.裝飾模式

向某個對象動態地添加更多的功能。修飾模式是除類繼承外另一種擴展功能的方法。

10.外觀模式

爲子系統中的一組接口提供一個一致的界面, 外觀模式定義了一個高層接口,這個接口使得這一子系統更加容易使用。

11.享元

通過共享以便有效的支持大量小顆粒對象。

12.代理

爲其他對象提供一個代理以控制對這個對象的訪問。

行爲型模式

13.職責鏈

爲解除請求的發送者和接收者之間耦合,而使多個對象都有機會處理這個請求。將這些對象連成一條鏈,並沿着這條鏈傳遞該請求,直到有一個對象處理它。

14.命令

將一個請求封裝爲一個對象,從而使你可用不同的請求對客戶進行參數化;對請求排隊或記錄請求日誌,以及支持可取消的操作。

15.解釋器

給定一個語言, 定義它的文法的一種表示,並定義一個解釋器, 該解釋器使用該表示來解釋語言中的句子。

16.迭代器

提供一種方法順序訪問一個聚合對象中各個元素, 而又不需暴露該對象的內部表示。

17.中介者

包裝了一系列對象相互作用的方式,使得這些對象不必相互明顯作用,從而使它們可以鬆散偶合。當某些對象之間的作用發生改變時,不會立即影響其他的一些對象之間的作用,保證這些作用可以彼此獨立的變化。

18.備忘錄

備忘錄對象是一個用來存儲另外一個對象內部狀態的快照的對象。備忘錄模式的用意是在不破壞封裝的條件下,將一個對象的狀態捉住,並外部化,存儲起來,從而可以在將來合適的時候把這個對象還原到存儲起來的狀態。

19.觀察者模式

在對象間定義一個一對多的聯繫性,由此當一個對象改變了狀態,所有其他相關的對象會被通知並且自動刷新。

20.狀態

讓一個對象在其內部狀態改變的時候,其行爲也隨之改變。狀態模式需要對每一個系統可能取得的狀態創立一個狀態類的子類。當系統的狀態變化時,系統便改變所選的子類。

21.策略

定義一個算法的系列,將其各個分裝,並且使他們有交互性。策略模式使得算法在用戶使用的時候能獨立的改變。

22.模板方法

模板方法模式準備一個抽象類,將部分邏輯以具體方法及具體構造子類的形式實現,然後聲明一些抽象方法來迫使子類實現剩餘的邏輯。不同的子類可以以不同的方式實現這些抽象方法,從而對剩餘的邏輯有不同的實現。先構建一個頂級邏輯框架,而將邏輯的細節留給具體的子類去實現。

23.訪問者

封裝一些施加於某種數據結構元素之上的操作。一旦這些操作需要修改,接受這個操作的數據結構可以保持不變。訪問者模式適用於數據結構相對未定的系統,它把數據結構和作用於結構上的操作之間的耦合解脫開,使得操作集合可以相對自由的演化。

空對象

通過提供默認對象來避免空引用。

黑板

廣義的觀察者在系統範圍內交流信息,允許多位讀者和寫者。

規格

以布爾形式表示的可重綁定的商業邏輯。

在面向對象軟件設計的發展過程中,除了《設計模式》一書中提到的23中設計模式之外,新的設計模式仍然不斷出現。


若想更進一步瞭解關於面向對象設計的背景,參考接口模式內聚耦合

若想更進一步瞭解關於面向對象編程的背景,參考繼承重載多態接口

參考來源:設計模式(wiki)




參考推薦:

設計模式筆記

設計模式(C#)

設計模式(C++)

設計模式(Java)

設計模式(JavaScript)

.NET設計模式系列文章(MS MVP)


UML 軟件工程組織推薦

設計模式推薦

設計模式(wiki)

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