天天看點

建立型-建造者模式

簡介

建造者模式又稱為builder模式,一般用來建構複雜對象,将複雜對象的建立與表示分離,使用者不需要了解建造的過程和細節。完整的建造者模式的結構模型如下:

建立型-建造者模式

完整的建造者模式包含四個角色:

builder:指定建立對象的各個部件的接口;

ConcreteBuilder:具體建造者,實作builder的接口;

product:最終建構成的具體産品;

director:指揮者直接和客戶進行需求溝通,并将客戶建立産品的請求劃分為對各個零件的建立請求,再将這些請求委托給具體建造者建造;           

模式實作

以網上訂購電腦舉例,産品為電腦(部件包括主機、顯示器、電源線三部分),指揮者相當于電商平台,而建造者為電腦廠家。使用者和平台溝通,平台委托廠家建立電腦并轉交給使用者。

産品,即電腦類:

@Data
public class Computer implements Serializable {
    ...
}           

建造者接口:

public interface ComputerBuilder {

    void buildMainEngine(); // 建造主機

    void buildMonitor(); // 建造顯示器

    void buildPowerCord(); // 建造電源線

    Computer returnComputer(); // 返還電腦産品
}           

具體建造者:

public class ComputerConcreteBuilder implements ComputerBuilder {

    private Computer computer = new Computer();

    @Override
    public void buildMainEngine() {
        System.out.println("建立主機。。");
    }

    @Override
    public void buildMonitor() {
        System.out.println("建立顯示器。。");
    }

    @Override
    public void buildPowerCord() {
        System.out.println("建立電源線。。");
    }

    @Override
    public Computer returnComputer() {
        return computer;
    }
}           

指揮者:

@NoArgsConstructor
public class ComputerDirector {

    private ComputerBuilder computerBuilder;

    public ComputerDirector(ComputerBuilder computerBuilder) {
        this.computerBuilder = computerBuilder;
    }

    public Computer buildComputer() {
        computerBuilder.buildMainEngine();
        computerBuilder.buildMonitor();
        computerBuilder.buildPowerCord();
        return computerBuilder.returnComputer();
    }
}           

實際使用:

public static void main(String[] args) {
        Computer computer = new ComputerDirector().buildComputer();
    }           

這樣,一個完整的建造者模式流程就完成了。

建造者模式一般一個具體建造者隻對應一個産品,如果有多個産品,則添加多個具體建造者。

模式退化

省略抽象建造者角色

如果确定隻需要一個具體建造者的話,那麼抽象建造者是可以省略的,抽象建造者角色的存在是為了規範具體建造者的行為,如果系統隻有一個具體建造者,那麼這個規範者角色就不需要了。

省略指揮者角色

如果抽象建造者角色被省略了,那麼指揮者角色也可以被省略,這時候具體建造者同時扮演指揮者和建造者兩個角色。

省略單獨的産品角色

這種情況适用于建造者構造的對象就是建造者自身,建造者同時扮演指揮者、建造者、産品三個角色。

jdk中的建造者模式

jdk中的建造者模式常見的就是SringBuffer和StringBuilder了,其中非線程安全的StringBuilder最為常用。AbstractStringBuilder作為抽象建造者,StringBuidler作為具體建造者,建造的對象是String,通過toString方法傳回。

此外,常用的鍊式調用也可以視為建造者模式,例如:

@Data
@Accessors(chain = true)
public class Computer implements Serializable {

    private static final long serialVersionUID = 3991323827696929155L;

    private String mainEngine;
    private String monitor;
    private String powerCord;

    public static void main(String[] args) {
        Computer computer = new Computer().setMainEngine("主機").setMonitor("顯示器").setPowerCord("電源線");
    }
}           

其中Computer為産品,

setMainEngine()

setMonitor()

setPowerCord()

是建構産品的部件方法,這種就是極簡類型的建造者模式。

與其他模式對比

與抽象工廠模式

在抽象工廠模式中,每一次工廠對象被調用時都會傳回一個産品對象,這個産品位于不同的産品等級結構中的一環,可能是一個最終的産品的一部分,而用戶端後續把産品組裝到成一個更大更複雜的産品;建造者模式則傳回一個完整的、最終的産品。

抽象工廠模式中,用戶端直接調用工廠方法擷取所需産品對象,而建造者模式中,用戶端可以通過指揮者間接擷取對象,且建造者類側重于一步步構造一個複雜對象,傳回一個完整的對象。

還使用上面例子,抽象工廠模式傳回産品族中的一個産品,例如隻傳回電腦主機;而建造者模式直接傳回整個電腦。

與模闆模式

當建造者模式退化到沒有指揮者,且抽象建造者使用抽象類,這樣完全可能變為模闆模式,隻要将具體建構産品部件方法的順序固定到返還産品方法中,并将返還産品不可重寫,就是一個合格的模闆模式。

實質上,兵無常勢,水無常形,實際代碼中嚴格按照設計模式定義的實作并不多,大多是退化之後的模式,而很多模式退化之後都非常相似,甚至可以互相轉化。