1. 程式人生 > 其它 >用一個例子說明設計模式五種建立型模式!

用一個例子說明設計模式五種建立型模式!

用一個例子說明設計模式五種建立型模式!!!

這是我寫設計模式的第二篇筆記隨筆,第一篇筆記隨筆連結:用現實生活中例項解釋說明設計模式六大基本原則

後續會在這個例子上擴充套件,包含其餘結構型模式和行為型模式,後續程式碼會上傳GitHub。

更多操作建立型模式 這些設計模式提供了一種在建立物件的同時隱藏建立邏輯的方式,而不是使用 new 運算子直接例項化物件。這使得程式在判斷針對某個給定例項需要建立哪些物件時更加靈活。

  • 工廠模式(Factory Pattern)
  • 抽象工廠模式(Abstract Factory Pattern)
  • 單例模式(Singleton Pattern)單例模式原理較為簡單,不作闡述,例子中使用到了單例模式
  • 建造者模式(Builder Pattern)
  • 原型模式(Prototype Pattern)

一輛汽車包含電氣部分(Electical)發動機(Engine)和外殼(Shell);然後衍生出了電氣部分工廠,發動機工廠和外殼工廠;寶馬(BMW)部件生產工廠,賓士(Benz)部件生產工廠等等……

以這個例子由簡單到複雜講解五種建立型模式

整體程式碼結構:

UML圖

UML簡圖

UML完整圖

工廠模式

簡單工廠模式

簡單工廠包含如下角色:

抽象產品 :定義了產品的規範,描述了產品的主要特性和功能。

具體產品 :實現或者繼承抽象產品的子類

具體工廠 :提供了建立產品的方法,呼叫者通過該方法來獲取產品。

抽象產品:

  • 電氣部分(Electical)
  • 發動機(Engine)
  • 外殼(Shell)

具體產品:

  • CarElectical
  • CarEngine
  • CarShell

具體工廠:

  • CarElecticalFactory
  • CarEngineFactory
  • CarShellFactory

優缺點

優點:

封裝了建立物件的過程,可以通過引數直接獲取物件。把物件的建立和業務邏輯層分開,這樣以後就避免了修改客戶程式碼,如果要實現新產品直接修改工廠類,而不需要在原始碼中修改,這樣就降低了客戶程式碼修改的可能性,更加容易擴充套件。

缺點:

增加新產品時還是需要修改工廠類的程式碼,違背了“開閉原則”。

工廠方法模式

定義一個用於建立物件的介面,讓子類決定例項化哪個產品類物件。工廠方法使一個產品類的例項化延遲到其工廠的子類。

工廠方法模式的主要角色:

  • 抽象工廠(Abstract Factory):提供了建立產品的介面,呼叫者通過它訪問具體工廠的工廠方法來建立產品。

  • 具體工廠(ConcreteFactory):主要是實現抽象工廠中的抽象方法,完成具體產品的建立。

  • 抽象產品(Product):定義了產品的規範,描述了產品的主要特性和功能。

  • 具體產品(ConcreteProduct):實現了抽象產品角色所定義的介面,由具體工廠來建立,它同具體工廠之間一一對應。

增加了抽象工廠MultiplePartsFactory:

優缺點

優點:

  • 使用者只需要知道具體工廠的名稱就可得到所要的產品,無須知道產品的具體建立過程;
  • 在系統增加新的產品時只需要新增具體產品類和對應的具體工廠類,無須對原工廠進行任何修改,滿足開閉原則;

缺點:

  • 每增加一個產品就要增加一個具體產品類和一個對應的具體工廠類,這增加了系統的複雜度。

抽象工廠模式

前面介紹的工廠方法模式中考慮的是一類產品的生產,如畜牧場只養動物、電視機廠只生產電視機;這些工廠只生產同種類產品,同種類產品稱為同等級產品,也就是說:工廠方法模式只考慮生產同等級的產品,但是在現實生活中許多工廠是綜合型的工廠,能生產多等級(種類) 的產品,如電器廠既生產電視機又生產洗衣機或空調,大學既有軟體專業又有生物專業等。

將同一個具體工廠所生產的位於不同等級的一組產品稱為一個產品族,下圖所示橫軸是產品等級,也就是同一類產品;縱軸是產品族,也就是同一品牌的產品,同一品牌的產品產自同一個工廠。

是一種為訪問類提供一個建立一組相關或相互依賴物件的介面,且訪問類無須指定所要產品的具體類就能得到同族的不同等級的產品的模式結構。抽象工廠模式是工廠方法模式的升級版本,工廠方法模式只生產一個等級的產品,而抽象工廠模式可生產多個等級的產品。

結構

抽象工廠模式的主要角色如下:

  • 抽象工廠(Abstract Factory):提供了建立產品的介面,它包含多個建立產品的方法,可以建立多個不同等級的產品。

  • 具體工廠(Concrete Factory):主要是實現抽象工廠中的多個抽象方法,完成具體產品的建立。

  • 抽象產品(Product):定義了產品的規範,描述了產品的主要特性和功能,抽象工廠模式有多個抽象產品。

  • 具體產品(ConcreteProduct):實現了抽象產品角色所定義的介面,由具體工廠來建立,它 同具體工廠之間是多對一的關係。

    舉例說明

抽象產品:

  • 電氣部分(Electical)
  • 發動機(Engine)
  • 外殼(Shell)

具體產品:

  • CarElectical
  • CarEngine
  • CarShell

具體工廠:

  • BenzFactory
  • BMWFactory
  • CarShellFactory

抽象工廠:

  • MultiplePartsFactory

優缺點

優點:

如果要加同一個產品族的話,只需要再加一個對應的工廠類即可,不需要修改其他的類。當一個產品族中的多個物件被設計成一起工作時,它能保證客戶端始終只使用同一個產品族中的物件。

缺點:

當產品族中需要增加一個新的產品時,所有的工廠類都需要進行修改。

使用場景

  • 當需要建立的物件是一系列相互關聯或相互依賴的產品族時,如電器工廠中的電視機、洗衣機、空調等。

  • 系統中有多個產品族,但每次只使用其中的某一族產品。如有人只喜歡穿某一個品牌的衣服和鞋。

  • 系統中提供了產品的類庫,且所有產品的介面相同,客戶端不依賴產品例項的建立細節和內部結構。

原型模式

用一個已經建立的例項作為原型,通過複製該原型物件來建立一個和原型物件相同的新物件。

結構

原型模式包含如下角色:

  • 抽象原型類:規定了具體原型物件必須實現的的 clone() 方法。
  • 具體原型類:實現抽象原型類的 clone() 方法,它是可被複制的物件。
  • 訪問類:使用具體原型類中的 clone() 方法來複制新的物件。

在這個例子中,讓BenzFactory 實現Cloneable介面,而BWM工廠使用了單例模式,即寶馬只在總部生產運往世界各地,而賓士在全世界各地開分廠。

使用場景

  • 物件的建立非常複雜,可以使用原型模式快捷的建立物件。
  • 效能和安全要求比較高。

建造者模式

概述

將一個複雜物件的構建與表示分離,使得同樣的構建過程可以建立不同的表示。

  • 分離了部件的構造(由Builder來負責)和裝配(由Director負責)。 從而可以構造出複雜的物件。這個模式適用於:某個物件的構建過程複雜的情況。
  • 由於實現了構建和裝配的解耦。不同的構建器,相同的裝配,也可以做出不同的物件;相同的構建器,不同的裝配順序也可以做出不同的物件。也就是實現了構建演算法、裝配演算法的解耦,實現了更好的複用。
  • 建造者模式可以將部件和其組裝過程分開,一步一步建立一個複雜的物件。使用者只需要指定複雜物件的型別就可以得到該物件,而無須知道其內部的具體構造細節。

結構

建造者(Builder)模式包含如下角色:

  • 抽象建造者類(Builder):這個介面規定要實現複雜物件的那些部分的建立,並不涉及具體的部件物件的建立。
  • 具體建造者類(ConcreteBuilder):實現 Builder 介面,完成複雜產品的各個部件的具體建立方法。在構造過程完成後,提供產品的例項。
  • 產品類(Product):要建立的複雜物件。
  • 指揮者類(Director):呼叫具體建造者來建立複雜物件的各個部分,在指導者中不涉及具體產品的資訊,只負責保證物件各部分完整建立或按某種順序建立。

在例子中:

  • 抽象建造者類:CarBuilder

  • 具體建造者類:BenzBuilder BMWBuilder

  • 產品類:Benz BMW

  • 指揮者類:BenzDirector BMWDirector

類圖如下:

優缺點

優點:

  • 建造者模式的封裝性很好。使用建造者模式可以有效的封裝變化,在使用建造者模式的場景中,一般產品類和建造者類是比較穩定的,因此,將主要的業務邏輯封裝在指揮者類中對整體而言可以取得比較好的穩定性。
  • 在建造者模式中,客戶端不必知道產品內部組成的細節,將產品本身與產品的建立過程解耦,使得相同的建立過程可以建立不同的產品物件。
  • 可以更加精細地控制產品的建立過程 。將複雜產品的建立步驟分解在不同的方法中,使得建立過程更加清晰,也更方便使用程式來控制建立過程。
  • 建造者模式很容易進行擴充套件。如果有新的需求,通過實現一個新的建造者類就可以完成,基本上不用修改之前已經測試通過的程式碼,因此也就不會對原有功能引入風險。符合開閉原則。

缺點:

造者模式所建立的產品一般具有較多的共同點,其組成部分相似,如果產品之間的差異性很大,則不適合使用建造者模式,因此其使用範圍受到一定的限制。

使用場景

建造者(Builder)模式建立的是複雜物件,其產品的各個部分經常面臨著劇烈的變化,但將它們組合在一起的演算法卻相對穩定,所以它通常在以下場合使用。

  • 建立的物件較複雜,由多個部件構成,各部件面臨著複雜的變化,但構件間的建造順序是穩定的。
  • 建立複雜物件的演算法獨立於該物件的組成部分以及它們的裝配方式,即產品的構建過程和最終的表示是獨立的。

工廠方法模式VS建造者模式

工廠方法模式注重的是整體物件的建立方式;而建造者模式注重的是部件構建的過程,意在通過一步一步地精確構造創建出一個複雜的物件。

抽象工廠模式VS建造者模式

抽象工廠模式實現對產品家族的建立,一個產品家族是這樣的一系列產品:具有不同分類維度的產品組合,採用抽象工廠模式則是不需要關心構建過程,只關心什麼產品由什麼工廠生產即可。建造者模式則是要求按照指定的藍圖建造產品,它的主要目的是通過組裝零配件而產生一個新產品。如果將抽象工廠模式看成汽車配件生產工廠,生產一個產品族的產品,那麼建造者模式就是一個汽車組裝工廠,通過對部件的組裝可以返回一輛完整的汽車。

執行

public class BuildMain {
    public static void main(String[] args) {
        BMWDirector bmwDirector = new BMWDirector(new BWMBuilder());
        BenzDirector benzDirector = new BenzDirector(new BenzBuilder());
        BMW bmw = bmwDirector.buildWholeCar();
        Benz benz = benzDirector.buildWholeCar();
        System.out.println(bmw.toString());
        System.out.println(benz.toString());

    }
}

/*

    組裝BMW電氣系統
            組裝BMW發動機
    組裝BMW車殼
            組裝benz電氣系統
    組裝benz發動機
            組裝benz車殼
    BMW{carElectical=CarElectical{name='BWM'}, carEngine=CarEngine{name='BWM'}, carShell=CarShell{name='BWM'}}
    Benz{carElectical=CarElectical{name='Benz'}, carEngine=CarEngine{name='Benz'}, carShell=CarShell{name='Benz'}}*/

未經作者同意請勿轉載

本文來自部落格園作者:aixueforever,原文連結:https://www.cnblogs.com/aslanvon/p/15305543.html