軟件設計要素初探:基礎設計模式概覽

「軟件設計要素初探」 一文,嘗試從軟件設計的總體角度,綜合討論了軟件設計的各類要素。本文討論基礎設計模式。

html

概述

設計模式是實現特定需求的接近代碼層面的設計套路,一般用於梳理和表達對象之間較爲複雜的依賴和交互關係,將錯綜複雜的容易膨脹的難以理解和擴展的條件判斷邏輯解開成一系列對象的清晰可理解的易擴展的交互結構。不一樣的設計模式之間有一些形式上的類似點,區分在於關注點不一樣。java

設計模式是軟件設計的入門指南,其主要理念是: 面向接口的編程,組合與委託優先於繼承。理解設計模式的關鍵點:關注點及目標用途、協做對象、靜態結構及動態交互。

git

基礎模式

經常使用的基礎設計模式有:github

工廠模式

  • 工廠模式(FactoryMethod):根據不一樣條件爲客戶端建立實現相同接口和功能的實例,而客戶端使用的是統一的功能接口。有點相似策略模式,不過工廠模式建立的是具有狀態和行爲的實例,而策略模式則是對行爲和算法建模。典型示例有 Spring Bean 工廠。 不少模式也須要聯合工廠模式,好比策略模式、模板方法模式等。

單例模式

  • 單例模式(Singleton):爲某類服務建立惟一的全局訪問點。多線程環境下需考慮併發建立問題,可以使用枚舉。典型示例有 Spring Component/Service 。

生成器模式

  • 生成器模式(Builder):複雜對象的建立,須要多個步驟或組合多個子部件完成,而且在這些步驟或組件完成以前,不容許該實例的生成。一般會私有化構造器,在構造的每一步驟中會設置某些屬性並返回其自身,便於鏈式調用,提供一個build方法生成知足某種實例建立契約的最終實例。好比汽車製造,就適用生成器模式。

可參閱 lombok 庫的 @Builder 註解。

正則表達式

抽象工廠模式

  • 抽象工廠模式(AbstractFactory): 系統含有多個相互協做的不一樣功能和特性的組件,每一個組件可定製爲不一樣的種類和風格。抽象工廠爲每一個組件的建立提供相對應的抽象工廠的建立接口,而由具體的工廠實現對應的組件建立接口。即有:XXXComponent 對應 XXXAbstractFactory , XXXAbstractFactory 含有一個 createXXXComponent 的建立接口,這裏 XXXComponent, XXXAbstractFactory 都是接口而不是實現。抽象工廠用於建立協做的多個組件實例的接口骨架。

原型模式

  • 原型模式(Prototype): 從現有對象實例快速生成和定製化對象實例,而不須要建立大量子類。原型模式特別適合於定製化。好比,現有一個房間對象,要建立含有炸彈的房間對象;這些房間對象的房間屬性都是同樣的,而這些炸彈多是不一樣種類,也多是相同種類只是顏色不一樣,使用普通的繼承結構和初始化操做會產生大量的相同的賦值代碼。此時使用原型模式很是恰當。經過一個含有普通炸彈的房間對象做爲原型進行克隆,而後設置炸彈的種類和屬性便可。原型模式使用有兩點:須要一個原型管理器進行原型註冊和查找;根據場景正確地實現淺拷貝和深拷貝。爲原型靜態或動態地增長屬性和行爲,能夠輕易地爲全部從該原型衍生的對象添加屬性和行爲。Javascript語言提供了原型機制。

適配器模式

  • 適配器模式(Adapter):複用現有類或對象的功能,實現客戶端須要的接口。有類適配器和對象適配器兩種。類適配器繼承現有類,能夠從新定義部分行爲;對象適配器使用現有類的對象實例並委託實現給該對象,可靈活使用多個現有對象。一般使用對象適配器。

組合模式

  • 組合模式(Composite): 具備層次性結構的單個對象與組合對象具備一致的接口,客戶端可以使用統一的接口操做局部和總體。樹形組件是典型示例。

可參閱: 「設計模式之組合模式:實現複合搜索條件構建」

算法

外觀模式

  • 外觀模式(Facade):爲複雜子系統提供簡單易用的接口,屏蔽實現的複雜性。庫的API,Java的正則對象(Compiler,Matcher)是典型的外觀模式應用。

裝飾器模式

  • 裝飾器模式(Decorator):具備相同接口的對象能夠在運行時動態組合成具備複合行爲的對象。能夠在運行時爲現有對象動態添加任意複雜的額外行爲。典型示例有 JavaIO框架。函數式編程是實現裝飾器模式的強大機制。

可參閱:「Java函數接口實現函數組合及裝飾器模式」「使用IntelljIDEA生成接口的類繼承圖及裝飾器模式」

編程

代理模式

  • 代理模式(Proxy): 爲對象或服務提供間接訪問機制。提供間接訪問的緣由可能有:隱藏源對象或源服務的部署細節(遠程代理);源對象建立開銷很大,只有須要的時候才建立(虛代理);訪問源對象須要某種權限或同步互斥(保護代理);須要爲訪問源對象和源服務增長額外的行爲(智能代理)。代理對象與源對象一般有一致的接口,並持有源對象的引用。

橋接模式

  • 橋接模式(Bridge):抽象部分與實現部分各具備獨立的繼承層次結構分開變化發展,使用橋接器將抽象繼承層次與實現繼承層次鏈接起來,實現並不直接繼承抽象類,而是抽象類持有實現類的引用。一般適用於這樣的場景:建立一個標準協議的接口框架,而接口框架的實現能夠有多種選擇,客戶端能夠根據須要選擇不一樣的實現。橋接器一般與抽象工廠模式、單例模式組合使用。典型應用有JDBC的接口與實現、日誌API接口與實現。

享元模式

  • 享元模式(Flyweight):大量不可變小對象的共享與管理。好比基礎類型裏的經常使用的26個字符對象、256個小整數對象、化學元素及原子等。可以使用緩存技術實現。爲了儘量節省內存開銷,須要識別享元對象中的外部狀態並從中移除,使得享元對象的共享達到最大化。享元模式可與抽象工廠模式、組合模式聯合使用。應用示例有使用面向對象技術建立的文檔編輯器。

模板方法模式

  • 模板方法模式(TemplateMethod):預先定義處理流程,對於流程中某些環節的具體處理留給具體業務去完成。模板方法模式應指明哪些是鉤子操做(可選重定義的,有默認實現),哪些是抽象操做(必須重定義的,沒有默認實現)。對於抽象操做,可使用統一命名前綴來識別,好比mustDoXXX. 典型示例有 Java容器框架。

可參閱:「設計模式之模板方法模式:實現可擴展性設計(Java示例)」

設計模式

策略模式

  • 策略模式(Strategy):爲特定任務提供多種實現算法,並在不一樣場景下可靈活切換而對客戶端透明。好比批量拉取數據的順序策略(簡單而略慢)以及併發策略(快速而略複雜)。使用策略模式時,客戶端可持有策略實現對象的接口或者策略實現對象的模板接口參數。具體應用例子有排序,提供多種排序策略,客戶端可根據須要採用所須要的排序實現(簡單性、穩定性、性能、內存佔用、多關鍵字、內存排序、文件排序)。

可參閱:「設計模式之策略模式:分離不一樣實現(Java示例)」

數組

觀察者模式

  • 觀察者模式(Observer):每一個對象都有一系列觀察者,當對象發生更新時推送更新給觀察者,由觀察者決定具體行爲。一般引伸爲訂閱-消費模式。GUI應用是觀察者模式的典型應用之一。

可參閱: 「設計模式之觀察者模式:實現配置更新實時推送」

緩存

職責鏈模式

  • 職責鏈模式(ResponsibiltyChain):將可以處理某種請求的多個對象串聯成一條處理鏈,請求沿着處理鏈傳遞給這些對象,對請求的發送者隱藏處理請求的實現細節(請求的發送者不須要知道誰真正處理這個請求)。 責任鏈上的請求處理對象能夠在運行時動態增減。責任鏈的實現中,鏈的構造和請求的傳遞既可使用全局控制器來配置、生成和控制(集中式策略),也能夠經過鏈上的對象來負責引用和傳遞(分散式策略)。須要構造兩種接口:請求接口和請求處理對象的接口,而請求處理對象則須要實現請求接口。請求處理對象的順序也值得斟酌,一般是從特殊到廣泛的順序。異常捕獲和處理機制便是職責鏈模式的具體應用例子之一。

命令模式

  • 命令模式(Command):將行爲封裝到通用接口中,經過命令調用。相似回調接口,可使用函數式編程實現。具體應用例子有JDBCTemplate。

可參閱: 「統計方法運行時間【Java實現】」

迭代器模式

  • 迭代器模式(Iterator):爲複雜的組合對象結構返回迭代器,安全訪問其中的元素,隱藏複雜的結構細節。典型示例有Java容器的迭代器,JDBC的ResultSet。

狀態模式

  • 狀態模式(State): 一個對象具備多種狀態,其某種複雜行爲取決於狀態及狀態變遷(代碼實現一般是一個大的Switch-If語句)。此時,能夠單獨將狀態及行爲抽離出來建模,並將對象的行爲委託狀態對象完成。若狀態行爲比較簡單,可使用具備行爲的枚舉或表來實現;若狀態行爲比較複雜,則須要使用狀態抽象類及具體狀態子類來實現。狀態對象可持有對象的引用,便於訪問所須要的信息。狀態子類沒有實例屬性,能夠實現爲單例類。常見的應用有:TCP鏈接狀態管理、虛擬機狀態管理、訂單狀態管理。

中介者模式

  • 中介者模式(Mediator):有多個基礎服務方,多個業務方;每一個業務方都有本身須要定製化的東西。若是全部業務方直接與各個基礎服務方打交道,會致使「服務方-業務方」的依賴關係激增(乘法關係),交互也變得複雜。引入中介者對象做爲服務方和業務方的調度調控,每一個基礎服務方和業務方只須要與中介者交互,而不須要知道具體的服務方和業務方。中介者對象將交互行爲集中化,簡化了依賴關係數量(加法關係)。 中介者對象在應用組織架構中俗稱「中臺」。

解釋器模式

  • 解釋器模式(Interpret):若是特定問題可使用一種簡單的語言來描述,那麼能夠定義一種文法,以及對應的解釋器。將問題的求解歸結爲根據文法構造句子,而後使用解析器來解釋句子生成結果。適用於領域語言設計和實現。典型例子有用於字符串匹配的正則表達式解析以及JSON解析。

可參閱: 「Java實現圖案打印: 記法與解釋器」

訪問模式

  • 訪問模式(Visitor):一個複雜的複合對象含有多個子對象 A,B,C, 對於每一個子對象都須要定義操做 op1, op2, op3, ... , opN ,而每一個子對象的操做 opi 均可能是不同的。 所有操做的定義放在這個複合對象裏,將使得這個複合對象異常的龐大臃腫。使用訪問器模式,能夠將這些操做抽離出來。每種操做都是一個訪問器ConcreteVisitor,能夠定義訪問接口visitA,visitB,visitC ; 每一個子對象以及該複合對象都有一個 accept(Visit) 的方法。複合對象的 accept 實現將委託給遍歷子對象的 accept 。 Visitor 主要用於爲複合對象定義可擴展的新操做。當定義一個新操做時,只須要增長一個新的ConcreteVisitor,而不須要改動現有的其餘類。若是子對象變化頻繁,那麼每一個 Visitor 都要增長一個 visitorX 的方法,Visitor模式就不適用了。

備忘錄模式

  • 備忘錄模式(Memento):歷史狀態存儲、撤銷與回退。

模式組合

組合是力量之源。每一個設計模式都有某個關注點,而這些關注點是相互協做的;具備協做關係的模式也是能夠組合的。能夠閱讀《面向模式的軟件架構》系列學習基礎模式如何組合而獲得更大的實用架構模式。這裏引用《設計模式:可複用面向對象軟件的基礎》的圖:
設計模式之間的關係和組合

模式示例

可參考我的工程 ALLIN 下的 src/main/java/zzz/study/patterns 包下的文件。

相關文章
相關標籤/搜索