天天看點

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

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

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

後續會在這個例子上擴充,包含其餘結構型模式和行為型模式,後續代碼會上傳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'}}*/

           

繼續閱讀