天天看點

設計模式—— 十一 :建造者模式什麼是建造者模式?建造者模式優缺點建造者模式的應用場景

文章目錄

建造者模式(Builder Pattern)也叫做生成器模式,其定義如下:

Separate the construction of a complex object from its representation so that the same construction process can create different representations.(将一個複雜對象的建構與它的表示分離,使得同樣的建構過程可以建立不同的表示。)

建造者模式一步一步建立一個複雜的對象,它允許使用者隻通過指定複雜對象的類型和内容就 可以建構它們,使用者不需要知道内部的具體建構細節。

建造者模式的通用類圖如圖11-1所示

圖11-1:建造者模式通用類圖

在建造者模式結構圖中包含如下幾個角色:

● Builder(抽象建造者):它為建立一個産品Product對象的各個部件指定抽象接口,在該接口中一般聲明兩類方法,一類方法是buildPartX(),它們用于建立複雜對象的各個部件;另一 類方法是getResult(),它們用于傳回複雜對象。Builder既可以是抽象類,也可以是接口。

●ConcreteBuilder(具體建造者):它實作了Builder接口,實作各個部件的具體構造和裝配方 法,定義并明确它所建立的複雜對象,也可以提供一個方法傳回建立好的複雜産品對象。

●Product(産品角色):它是被建構的複雜對象,包含多個組成部件,具體建造者建立該産品 的内部表示并定義它的裝配過程。

● Director(指揮者):指揮者又稱為導演類,它負責安排複雜對象的建造次序,指揮者與抽 象建造者之間存在關聯關系,可以在其construct()建造方法中調用建造者對象的部件構造與裝 配方法,完成複雜對象的建造。用戶端一般隻需要與指揮者進行互動,在用戶端确定具體建 造者的類型,并執行個體化具體建造者對象(也可以通過配置檔案和反射機制),然後通過指揮 者類的構造函數或者Setter方法将該對象傳入指揮者類中。

建造者模式的通用源代碼也比較簡單。

  • Product(産品角色)

    在建造者模式的定義中提到了複雜對象,那麼什麼是複雜對象?簡單來說,複雜對象是指那 些包含多個成員屬性的對象,這些成員屬性也稱為部件或零件,如汽車包括方向盤、發動 機、輪胎等部件,電子郵件包括發件人、收件人、主題、内容、附件等部件

public class Product { 
    private String partA; //定義部件,部件可以是任意類型
    private String partB; 
    private String partC;
    //省略getter、setter方法
    
}      
  • Builder(抽象建造者)

    在抽象類Builder中聲明了一系列抽象的buildPartX()方法用于建立複雜産品的各個部件,具體 建造過程在ConcreteBuilder中實作,此外還提供了工廠方法getResult(),用于傳回一個建造好的完整産品。

public abstract class Builder {
    //建立産品對象
    protected Product product=new Product(); 
    public abstract void buildPartA(); 
    public abstract void buildPartB(); 
    public abstract void buildPartC(); //傳回産品對象 

    public Product getResult() {
        return product;
    }
}      
  • ConcreteBuilder(具體建造者)

    在ConcreteBuilder中實作了buildPartX()方法,通過調用Product的setPartX()方法可以給産品對象 的成員屬性設值。不同的具體建造者在實作buildPartX()方法時将有所差別,如setPartX()方法 的參數可能不一樣,在有些具體建造者類中某些setPartX()方法無須實作(提供一個空實 現)。而這些對于用戶端來說都無須關心,用戶端隻需知道具體建造者類型即可。

public class ConcreteProduct extends Builder{

    @Override
    public void buildPartA() {
        //具體實作
    }

    @Override
    public void buildPartB() {
        //具體實作
    }

    @Override
    public void buildPartC() {
         //具體實作
    }

}      
  • Director(指揮者)

    指揮者類Director主要有兩個作用:一方面它隔離 了客戶與建立過程;另一方面它控制産品的建立過程,包括某個buildPartX()方法是否被調用 以及多個buildPartX()方法調用的先後次序等。指揮者針對抽象建造者程式設計,用戶端隻需要知 道具體建造者的類型,即可通過指揮者類調用建造者的相關方法,傳回一個完整的産品對 象。在實際生活中也存在類似指揮者一樣的角色,如一個客戶去購買電腦,電腦銷售人員相 當于指揮者,隻要客戶确定電腦的類型,電腦銷售人員可以通知電腦組裝人員給客戶組裝一 台電腦。

public class Director {
    private Builder builder;

    public Director(Builder builder) {
        this.builder = builder;
    }

    public void setBuilder(Builder builder) {
        this.builder = builder;
    }
    
    //産品建構與組裝方法 
    public Product construct() { 
        builder.buildPartA();
        builder.buildPartB(); builder.buildPartC();
        return builder.getResult();
    }
}      

導演類起到封裝的作用,避免高層子產品深入到建造者内部的實作類。當然,在建造者模 式比較龐大時,導演類可以有多個。

● 封裝性 使用建造者模式可以使用戶端不必知道産品内部組成的細節。

● 建造者獨立,容易擴充 BenzBuilder和BMWBuilder是互相獨立的,對系統的擴充非常有利。

● 便于控制細節風險 由于具體的建造者是獨立的,是以可以對建造過程逐漸細化,而不對其他的子產品産生任 何影響。

● 建造者模式所建立的産品一般具有較多的共同點,其組成部分相似,如果産品之間的差異 性很大,例如很多組成部分都不相同,不适合使用建造者模式,是以其使用範圍受到一定的 限制。

● 如果産品的内部變化複雜,可能會導緻需要定義很多具體建造者類來實作這種變化,導緻系統變得很龐大,增加系統的了解難度和運作成本。

  • 需要生成的産品對象有複雜的内部結構,這些産品對象通常包含多個成員屬性。
  • 需要生成的産品對象的屬性互相依賴,需要指定其生成順序。
  • 對象的建立過程獨立于建立該對象的類。在建造者模式中通過引入了指揮者類,将建立過 程封裝在指揮者類中,而不在建造者類和客戶類中。
  • 隔離複雜對象的建立和使用,并使得相同的建立過程可以建立不同的産品。

繼續閱讀