設計模式(1)——簡介(翻譯自維基百科wiki)
說明(Tips)
翻譯維基百科對於設計模式的相關描述。後續會有對23中設計模式的實踐。
表格內容處正在更新中(暫時只更新23個設計模式內容)
此文章主要內容:
- 設計模式發展歷史
- 設計模式學習的價值所在
- 書籍推薦。在“發展歷史(History)”章節最後,有學習設計模式的經典教材。其中在“文件(Document)”章節介紹了經典書籍《設計模式》的組織結構,相信對於《設計模式》的學習框架有一個整體的瞭解。
概述(Header summary)
在軟體工程領域,設計模式:是對給定軟體設計需求情況下的一種通常的,可複用的解決方案。然而它並不是一種能直接轉化成原始碼或者機器程式碼的設計,而是一種能夠應用在許多不同情境下的解決問題的模板描述。對程式設計師來說,當他們在設計一個應用或者系統時,設計模式是一種解決一般性問題的形式化的最佳實踐。
面向物件設計模式在不需要指定與最終應用程式相關的類與物件的情況下,經典地展示出類與物件之間的關係與互動。需要注意的是:那些隱含易變狀態的設計模式很可能不適用於函數語言程式設計語言;某些語言使用特定的設計模式可能顯得沒有必要,因為這些語言可能已經內建了對特定設計模式解決問題的方案;面向物件的設計模式不見得適用於非面向物件的程式設計語言。
設計模式可被視為一種結構化的計算機程式設計橋樑,此橋樑連線程式設計正規化與具體演算法。
發展歷史(History)
模式起源於 Christopher Alexandert提出的建築學概念。 在 1987年, Kent Beck 和Ward Cunningham開始在程式設計上試驗一些模式——模式語言,並且在那年的OOPSLA(Object-Oriented Programming, Systems, Languages & Applications)會議上展示了他們的成果。在接下來的數年裡,Beck, Cunningham還有許多科學家相繼開始這方面的研究。
在1994年 的《Design Patterns: Elements of Reusable Object-Oriented Software》(設計模式:可複用面向物件軟體的基礎)這本書被出版後,設計模式在電腦科學領域廣為流傳。這本書的作者們被稱為“Gang of Four”(四人幫),通常我們簡寫為”GoF“。同一年,首屆“ Pattern Languages of Programming Conference”會議召開。接下來的一年,“Portland Pattern Repository ”(波蘭模式庫)——為設計模式文件而建立的文件庫建立了。
有關設計模式的著名書籍
如下(注:點選連結為國內版本,劃線代表國內沒出版):
-
《設計模式:可複用面向物件軟體的基礎》
[1995]《Design Patterns: Elements of Reusable Object-Oriented Software》 -
《Head First 設計模式》
[2004]《Head First Design Patterns》 -
《面向模式的軟體架構 第1卷:模式系統》
[1996]《Pattern-Oriented Software Architecture, Volume 1: A System of Patterns》 -
《面向模式的軟體架構. 第2卷:併發和聯網物件模式》
[2000]《Pattern-Oriented Software Architecture, Volume 2: Patterns for Concurrent and Networked Objects》 -
《企業應用架構模式》
[2002]《Patterns of Enterprise Application Architecture》 -
[2003]《 Enterprise Integration Patterns: Designing, Building, and Deploying Messaging Solutions》 -
[1995]《Studies in Computational Science: Parallel Programming Parad》 -
[1997]《Smalltalk Best Practice Patterns》
雖然設計模式已經被實踐應用很長時間了,但是有關設計模式概念的形式化多年來仍然沒有很大進展。
實踐(Practice)
設計模式通過提供久經考驗且被證實的開發正規化加速開發程序。有效的軟體設計需要考慮那些在程式碼實現時才可能顯現的一些問題。剛完成的程式碼常常隱藏著細小的問題,這些問題可能需要花些日子才能被檢測到並且這些問題常常會導致程式出現重大問題(bug)。複用設計模式能預防這樣的問題並且給程式設計師和架構師提升了程式碼的可讀性。
為了實現靈活性,設計模式通常會引入額外的中間構建物,這種情況可能會導致最終設計變得複雜,降低程式的效能。
按照定義,一個模式必須通過再程式設計的方式進入程式程式碼中。由於一些作者將此視為從由組建提供的軟體重用向後退一步,研究者就努力將模式轉化為元件。 Meyer 和Arnout就曾提供了2/3設計模式的完整或者部分的元件。
軟體設計技術很難應用到覆蓋範圍很廣的問題上。它只提供一種普遍的,具有一般性地解決方案,並且以形式記錄下來,這種形式不指定在特定問題上的特定細節。
模式分類與列表(Classification and list)
設計模式最初被分為三類:creational patterns(建立型), structural patterns(結構型),behavioral patterns(結構型),並且使用 delegation(委託), aggregation(聚合), consultation(協商)等概念加以描述。對於面向物件設計,有 coupling(耦合) ,cohesion(內聚), inheritance(繼承), interface(介面), polymorphism(多型)等概念。
另一個分類方法引入了架構設計模式( architectural design pattern)的概念,它可能會被應用到軟體架構級別,例如 MVC(Model–View–Controller)模型。
建立型(Creational patterns)
注:“In Design Patterns”表示 《設計模式》是否涵蓋此模式內容,同理“In Code Complete”
表示《程式碼大全》。Other代表其它文獻。
點選相應的連結,可以檢視相應書籍的豆瓣介紹。
名稱 | 描述 | In Design Patterns | In Code Complete | Other |
---|---|---|---|---|
抽象工廠 Abstract factory |
提供一個介面用來建立一系列相關或者獨立的物件但並不制定他們的具體類 | Yes | Yes | N/A |
工廠方法 Factory method |
定義一個介面用來建立一個單一物件,但是由子類決定哪個類將被初始化。工廠方法讓一個類推遲初始化任務給子類。. | Yes | Yes | N/A |
建造者 Builder |
.隔離一個複雜物件的構造與表現,允許同一構造器建立多樣的表現。 | Yes | No | N/A |
單例 Singleton |
確保一個類只能被初始化一次,並對外提供一個統一的訪問點來獲取這個例項。 | Yes | Yes | N/A |
原型 Prototype |
指定使用原型例項建立的物件的種類,並從現有物件的“骨架”建立新物件,從而提高效能並將記憶體佔用量保持在最小值。 | Yes | No | N/A |
依賴注入 Dependency Injection |
. | |||
延遲初始化 Lazy initialization |
. | PoEAA | ||
多例 Multiton |
. | |||
物件池 Object Pool |
. | |||
資源獲取即初始化 Resource acquisition is initialization (RAII) |
. |
結構型(Structural patterns)
名稱 | 描述 | In Design Patterns | In Code Complete | Other |
---|---|---|---|---|
外觀 Facade |
為一個子系統中的一系列介面對外提供統一的介面。外觀模式提供讓子系統更易使用的更高層次的介面 | Yes | Yes | N/A |
裝飾器 Decorator |
動態附加額外的職責給物件以保持相同的介面。裝飾器對子類繼承功能來說提供靈活了的可選方案。 | Yes | Yes | N/A |
介面卡、包裝器或翻譯器 Adapter, Wrapper, or Translator |
將一個類的介面轉化成客戶端所期待的其它介面。介面卡讓本不相容的類一起協同工作。企業整合模式等同於譯者(translator) | Yes | Yes | N/A |
享元 Flyweight |
利用共享有效地支援大量類似的物件 | Yes | No | N/A |
組合 Composite |
將物件組合成樹形結構來表示部分與整體的層級繼承關係。能讓客戶端統一的看待單獨的物件和由這些物件組成的組建 | Yes | Yes | N/A |
橋接 bridge |
從類的實現上解耦出一個抽象,讓兩者單獨變化 | Yes | Yes | N/A |
代理 Proxy |
為控制訪問類的物件提供一個代理,或者說佔位 | Yes | No | N/A |
擴充套件物件 Extension object |
新增功能到某個層級而不影響層級的繼承關係 | No | No | 敏捷軟體開發 |
前端控制器 Front controller |
此模式跟web開發相關。它提供一個處理請求的集中入口。 | No | No | J2EE核心模式 ,《企業應用架構模式》 |
標記 Marker |
與類的元資料相關聯的空介面 | No | No | Effective java |
模組 Module |
組合若干個相關聯的元素形成單一的實體類。相關聯的元素例舉:classes,singletons,methods等 | No | No | N/A |
孿生兄弟 Twin |
對於不支援多繼承的程式語言來說,Twin提供了允許多繼承的解決方案 | No | No | N/A |
行為型(Behavioral patterns)
併發型(Concurrency patterns)
文件(Document)
設計模式的文件描述了模式被應用的上下文,模式解決上下文中的衝突,還有推薦的解決方案。沒有單一或者標準的形式來記錄設計模式。當然,有許多的格式被不同的模式作者使用。然而,Martin Fowler——一種非常著名的模式形式已經成為公認的新模式的寫作首要考慮的形式。
GoF的文件格式就是一個例子:
- 模式名與分類(Pattern Name and Classification): A descriptive and unique name that helps in identifying and referring to the pattern.
- 目的(Intent): A description of the goal behind the pattern and the reason for using it.
- 已知的(Also Known As): Other names for the pattern.
- 動機(Motivation (Forces) ): A scenario consisting of a problem and a context in which this pattern can be used.
- 適用性(Applicability): Situations in which this pattern is usable; the context for the pattern.
- (結構)Structure: A graphical representation of the pattern. Class diagrams and Interaction diagrams may be used for this purpose.
- (參與者)Participants: A listing of the classes and objects used in the pattern and their roles in the design.
- (協作)Collaboration: A description of how classes and objects used in the pattern interact with each other.
- (結果)Consequences: A description of the results, side effects, and trade offs caused by using the pattern.
- (實現)Implementation: A description of an implementation of the pattern; the solution part of the pattern.
- (樣例程式碼)Sample Code: An illustration of how the pattern can be used in a programming language.
- (應用場景)Known Uses: Examples of real usages of the pattern.
- (相關模式)Related Patterns: Other patterns that have some relationship with the pattern; discussion of the differences between the pattern and similar patterns.
批評(Criticism)
我們注意到,設計模式可能僅僅只是一些程式語言(Java,C++等)所缺少的特性的標誌。 Peter Norvig證明了Design Patterns書中23個設計模式中的16個 在Lisp 或者 Dylan語言中都被簡化了或者被淘汰了,因為這些語言直接支援了這些模式。Hannemann 和Kiczales使用面向切面程式語言( aspect-oriented programming language (AspectJ) )實現了23個設計模式中的若干個,他們做出的相關觀察結果展示了程式碼層的依賴從23個設計模式中的17個實現中移除了,並且面向介面程式設計能簡化設計模式的實現。如果有興趣可以看看Paul Graham對於此話題討論文章。