1. 程式人生 > 其它 >設計模式總結:建立型模式

設計模式總結:建立型模式

建立型模式

目錄
  • 類模式
    • 工廠方法模式
  • 物件模式
    • 抽象工廠模式
    • 建造者模式
    • 原型模式
    • 單例模式

1 簡單工廠模式 Simple Factory

1.1 定義

  • 簡單工廠模式(Simple Factory Pattern),又稱為靜態工廠方法(Static Factory Method)模式
  • 根據引數的不同返回不同類的例項
  • 專門定義一個類來負責建立其他類的例項,被建立的例項通常具有共同的父類

包含如下角色

  • Factory 工廠角色
  • Product 抽象產品角色
  • ConcreteProduct 具體產品角色

1.2 模式分析

  • 物件的建立物件本身業務處理分離可以降低系統的耦合度 ,使得兩者修改起來都相對容易。

  • 簡單工廠模式的要點在於:當你需要什麼,只需要傳入一個正確的引數,就可以獲取你所需要的物件,而無須知道其建立細節。

  • 優點

    • 實現了對責任的分割,提供專門的工廠類用於建立物件
    • 客戶端無需知道所建立的具體產品類目,只需要知道產品類對應的引數即可
    • 引入配置檔案,可以在不修改客戶端程式碼的情況下更換和新增新的具體產品類
  • 缺點

    • 工廠類集合了所有產品建立邏輯,一旦不能工作,整個系統都會被影響
    • 會增加類的個數
    • 拓展困難,一旦新增新產品,就不得不修改工廠邏輯(違背了開閉原則)
  • 適用

    • 工廠類負責建立的物件比較少(不會導致工廠的邏輯太複雜)
    • 客戶端只知道傳入工廠類的引數,對於如何建立物件不關心
  • 簡化

    • 可以把靜態工廠方法寫到抽象產品類中

1.3 例子

  • 根據不同的許可權等級建立不同的使用者物件,不同的使用者物件擁有不同的操作許可權

  • JDK日期格式化類

  • JDK加密技術

2 工廠方法模式 Factory Method

2.1 模式動機

考慮簡單工廠的不足,即要增加新產品時,除了增加一個新的具體產品類之外,還需要修改工廠類的程式碼,這就使得整個設計在一定程度上違反了“開閉原則 ”

修改:不再設計一個工廠類來統一負責所有產品的建立,而是將具體類的建立過程交給專門的工廠子類去完成

2.2 定義

  • 工廠方法模式(Factory Method Pattern)又稱為工廠模式,也叫虛擬構造器(Virtual Constructor)模式或者多型工廠(Polymorphic Factory)模式

2.3 模式分析

  • 在工廠方法模式中,核心的工廠類不再負責所有產 品的建立,而是將具體建立工作交給子類去做。因此,工廠方法模式可以允許系統在不修改工廠角色的情況下引進新產品(符合開閉原則)

  • 在定義工廠和產品時都必須使用抽象層,如果需要更換產品類,只需要更換對應的工廠即可,其他代 碼不需要進行任何修改。

  • 優點

    • 使用者只需關心所需產品對應的工廠,無需關心建立細節,甚至無需知道具體產品類名
    • 工廠可以自主確定如何建立何種產品物件,如何建立物件的細節完全封裝在工廠內部
    • 引入新產品時,無需修改抽象工廠和產品,無需修改客戶端,也無需修改其他具體工廠和產品,只需要新增一個具體產品和工廠類即可
  • 缺點

    • 引入新產品時,需要引入具體工廠類,一定程度上增加了系統的複雜度
    • 客戶端中需要使用對抽象層的定義,增加系統的抽象性和理解難度,需要用到反射等技術
  • 適用

    • 一個類不知道它所需要的物件的類
    • 一個類通過其子類來指定建立哪個物件
    • 將建立物件的任務委託給多個工廠子類中的一個,在使用時動態指定

2.4 例子

3 抽象工廠模式 Abstract Factory

3.1 模式動機

  • 工廠方法中,一個具體工廠對應一種具體產品
  • 有時候我們為需要一個工廠可以提供多個產品物件,而不是單一的產品物件

3.2 定義

  • 抽象工廠模式(Abstract Factory Pattern):提供一個建立一系列相關或相互依賴物件的介面,而無須指定它們具體的類。抽象工廠模式又稱為Kit模式,屬於物件建立型模式

引入兩個概念

  • 產品等級結構:即產品的繼承結構,如抽象電視機是父類,具體品牌的電視機是其子類
  • 產品族:指由同一個工廠生產的,位於不同產品等級結構中的一組產品

包含以下角色:

  • AbstractFactory
  • ConcreteFactory
  • AbstractProduct
  • Product

3.3 模式分析

  • 優點

    • 隔離了具體類的生成,使得客戶端不需要知道什麼被建立
    • 所有的具體工廠都實現了抽象工廠中的公共介面,只需要替換具體工廠,就可以改變整個軟體系統的行為
    • 高內聚、低耦合
    • 保證客戶端始終使用同一個產品族的物件
    • 增加新的具體工廠和產品族很方便,無需修改已有系統(開閉原則)
  • 缺點

    • 新增新的產品時,很難擴充套件抽象工廠來生成新的產品
    • 新增新的產品族和工廠容易,新增新的產品等級結構難。即開閉原則的傾斜性
  • 適用

    • 一個系統不應當依賴產品類例項如何被建立、組合和表達的細節(對所有工廠模式都很重要)
    • 系統中有多個產品族,且每次只用一個
    • 屬於同一個產品族的產品將在一起使用
    • 系統提供一個產品族的庫,所有的產品以同樣的接口出現,從而使客戶端不依賴於具體實現

3.4 例子

  • 一個電器工廠可以生產多個型別的電器,有多個工廠

  • 針對不同的資料庫,提供Connector和Statement

4 工廠模式退化

5 建造者模式 Builder

建造者模式(Bulider模式)詳解 (biancheng.net)

5.1 模式動機

  • 存在一些複雜的物件,有多個組成部分,如汽車包括輪胎、方向盤等,而對於大多數使用者而言,無須知道這些部件的裝配細節,也幾乎不會使用單獨某個部件,而是使用一輛完整的汽車
  • 建造者模式可以將部件和其組裝過程分開,一步一步建立一個複雜的物件
  • 建造者返還給客戶端的是一個已經建造完畢的完整產品物件,而使用者無須關心該物件所包含的屬性以及它們的組裝方式。

5.2 定義

  • 建造者模式(Builder Pattern):將一個複雜物件的構建與它的表示分離,使得同樣的構建過程可以建立不同的表示。

包含以下角色

  • Builder:抽象建造者
  • ConcreteBuilder:具體建造者
  • Director:指揮者
  • Product:產品角色

5.3 模式分析

  • 引入指揮者類,一方面它隔離了客戶與生產過 程;另一方面它負責控制產品的生成過程。

  • 在客戶端程式碼中,無需關心產品物件的具體組裝過程,只需確定具體的建造者型別即可

  • 優點

    • 客戶端不必知道產品內部組成的細節,將產品本身與產品的建立過程解耦,使得相同的建立過程可以建立不同的產品物件。
    • 每一個具體建造者都相對獨立,而與其他的具體建造者無關,使用者使用不同的具體建造者即可得到不同的產品物件。
    • 可以更加精細地控制產品的建立過程。
    • 增加新的具體建造者無須修改原有類庫的程式碼,指揮者類針對抽象建造者類程式設計,系統擴充套件方便,符合“開閉原則”。
  • 缺點

    • 如果產品之間的差異性很大,則不適合使用建造者模式,因此其使用範圍受到一定的限制。
    • 如果產品的內部變化複雜,可能會導致需要定義很多具體建造者類來實現這種變化,導致系統變得很龐大
  • 適用

    • 需要生成的產品物件有複雜的內部結構,這些產品物件通常包含多個成員屬性。
    • 需要生成的產品物件的屬性相互依賴,需要指定其生成順序。
    • 物件的建立過程獨立於建立該物件的類。在建造者模式中引入了指揮者類,將建立過程封裝在指揮者類中,而不在建造者類中。
    • 隔離複雜物件的建立和使用,並使得相同的建立過程可以建立不同的產品
  • 簡化

    • 省略抽象建造者角色:如果系統中只需要一個具體建造 者的話,可以省略掉抽象建造者。
    • 省略指揮者角色:在具體建造者只有一個的情況下,如 果抽象建造者角色已經被省略掉,那麼還可以省略指揮 者角色,讓Builder角色扮演指揮者與建造者雙重角色。

5.4 例子

建造者模式可以用於描述KFC如何建立套餐:套餐是一個複雜物件,它一般包含主食(如漢堡、雞肉卷等)和 飲料(如果汁、可樂等)等組成部分,不同的套餐有不同的組成部分,而KFC的服務員可以根據顧客的要求, 一步一步裝配這些組成部分,構造一份完整的套餐,然後返回給顧客

5.5 對比

通過前面的學習,我們已經瞭解了建造者模式,那麼它和工廠模式有什麼區別呢?

  • 建造者模式更加註重方法的呼叫順序,工廠模式注重建立物件。
  • 建立物件的力度不同,建造者模式建立複雜的物件,由各種複雜的部件組成,工廠模式創建出來的物件都一樣
  • 關注重點不一樣,工廠模式只需要把物件創建出來就可以了,而建造者模式不僅要創建出物件,還要知道物件由哪些部件組成。
  • 建造者模式根據建造過程中的順序不一樣,最終物件部件組成也不一樣。

6 原型模式 Prototype

6.1 模式動機

  • 使用原型模式來複制一個物件自身, 從而克隆出多個與原型物件一模一樣的物件
  • 在軟體系統中,有些物件的建立過程較為複雜,而且有時候需要頻繁建立,原型模式通過給出一個原型物件來指明 所要建立的物件的型別,然後用複製這個原型物件的辦法創建出更多同類型的物件,這就是原型模式的意圖所在。

6.2 定義

  • 原型模式(Prototype Pattern):原型模式是一種物件建立型模式,用原型例項指定建立物件的種類,並且通過復 制這些原型建立新的物件。

  • 原型模式允許一個物件再建立另外一個可定製的物件,無須知道任何建立的細節。

原型模式包含如下角色:

  • Prototype:抽象原型類
  • ConcretePrototype:具體原型類
  • Client:客戶類

6.3 模式分析

  • 一個類包含一些成員物件,在使用原型模式克隆物件時,根據其成員物件是否也克隆,原型模式可以分為兩種形式:深克隆和淺克隆

  • JAVA中有clone方法

    • 所有的Java 類都繼承自java.lang.Object,而Object類提供一個 clone()方法,可以將一個Java物件複製一份
    • 能夠實現克隆的Java類必須實現一個標識介面Cloneable, 表示這個Java類支援複製。如果一個類沒有實現這個接 口但是呼叫了clone()方法,Java編譯器將丟擲一個 CloneNotSupportedException異常。
    • 對任何的物件x,都有x.clone()!=x,即克隆物件與 原物件不是同一個物件。
    • 對任何的物件x,都有 x.clone().getClass()==x.getClass(),即克隆物件與原 物件的型別一樣。
    • 如果物件x的equals()方法定義恰當,那麼 x.clone().equals(x)應該成立。
  • 優點

    • 使用原型模式可以簡化物件的建立過程,通過一個已有例項可以提高新例項 的建立效率。
    • 可以動態增加或減少產品類。
    • 原型模式提供了簡化的建立結構。
    • 可以使用深克隆的方式儲存物件的狀態
  • 缺點

    • 需要為每一個類配備一個克隆方法,對已有的類進行改造時,不一定是件容易的事, 必須修改其原始碼,違背了“開閉原則”。
    • 在實現深克隆時需要編寫較為複雜的程式碼
  • 適用

    • 建立新物件成本較大
    • 如果系統要儲存物件的狀態,而物件的狀態變化很小,或者物件本身佔記憶體不大的時候
    • 需要避免使用分層次的工廠類來建立分層次的物件,並且類的例項物件只有一個或很少的幾個組合狀態,通過複製原型物件 得到新例項可能比使用建構函式建立一個新例項更加方便
  • 擴充套件

    • 原型管理器原型模式(原型設計模式)詳解 (biancheng.net)

    • 相似物件的複製

      很多情況下,複製所得到的物件與原型物件並不是完全相同的,它們的某些屬性值存在異同。通過原型模式獲 得相同物件後可以再對其屬性進行修改,從而獲取所需物件。

6.4 例子

  • 原型模式應用於很多軟體中,如果每次建立一個物件要花大量時間,原型模式是最好的解決方案。很多軟體提 供的複製(Ctrl + C)和貼上(Ctrl + V)操作就是原型模式的應用
  • 在Spring中,使用者也可以採用原型模式來建立新的bean例項,從而實現每次獲取的是通過克隆生成的新例項,對其進行修改時對原有例項物件不造成任何影響。