java設計模式之建造者模式

建造者模式:將一個複雜對象的構建與它的表示分離,使得同樣的構建過程可以創建不同的表示。

建造者模式其實就是使用多個簡單對象一步步的創建一個複雜對象。用戶只需要給出指定複雜對象的類型和內容,建造者模式負責按順序創建複雜對象(把內部的建造過程和細節隱藏起來)。

建造者模式符合依賴倒置原則:

  • 高層次的模塊不應該依賴於低層次的模塊,他們都應該依賴於抽象。
  • 抽象不應該依賴於具體實現,具體實現應該依賴於抽象。

建造者模式UML類圖:

  1. Builder:給出一個抽象接口,以規範產品對象的各個組成成分的建造。這個接口規定要實現複雜對象的哪些部分的創建,並不涉及具體的對象部件的創建。
  2. ConcreteBuilder:實現Builder接口,針對不同的商業邏輯,具體化複雜對象的各部分的創建。 在建造過程完成後,提供產品的實例。
  3. Director:聚合關聯Builder,調用具體建造者來創建複雜對象的各個部分,在指導者中不涉及具體產品的信息,只負責保證對象各部分完整創建或按某種順序創建。
  4. Product:要創建的複雜對象。

建造者模式代碼:

//Director接口
interface AirShipDirector {
    //組裝船對象
    AirShip   directAirShip();
}
//Builder接口
interface AirShipBuilder {
    Engine builderEngine();
    OrbitalModule builderOrbitalModule();
    EscapeTower  builderEscapeTower();
}
//Builder實現類
class SxtAirShipBuilder implements AirShipBuilder {
    @Override
    public Engine builderEngine() {
        System.out.println("構建飛天發動機!");
        return new Engine("飛天發動機!");
    }
    @Override
    public EscapeTower builderEscapeTower() {
        System.out.println("構建逃逸塔");
        return new EscapeTower("飛天逃逸塔");
    }
    @Override
    public OrbitalModule builderOrbitalModule() {
        System.out.println("構建軌道艙");
        return new OrbitalModule("飛天軌道艙");
    }
}
//Director實現類
class SxtAirshipDirector implements AirShipDirector {

    private AirShipBuilder builder;

    public SxtAirshipDirector(AirShipBuilder builder) {
        this.builder = builder;
    }


    @Override
    public AirShip directAirShip() {
        Engine e = builder.builderEngine();
        OrbitalModule o = builder.builderOrbitalModule();
        EscapeTower et = builder.builderEscapeTower();
        //裝配成飛船對象
        AirShip ship = new AirShip();
        ship.setEngine(e);
        ship.setEscapeTower(et);
        ship.setOrbitalModule(o);
        return ship;
    }
}
//實體類
class AirShip {
    private OrbitalModule orbitalModule;  //軌道艙
    private Engine engine; //發動機
    private EscapeTower escapeTower;  //逃逸塔

    public OrbitalModule getOrbitalModule() {
        return orbitalModule;
    }
    public void setOrbitalModule(OrbitalModule orbitalModule) {
        this.orbitalModule = orbitalModule;
    }
    public Engine getEngine() {
        return engine;
    }
    public void setEngine(Engine engine) {
        this.engine = engine;
    }
    public EscapeTower getEscapeTower() {
        return escapeTower;
    }
    public void setEscapeTower(EscapeTower escapeTower) {
        this.escapeTower = escapeTower;
    }

    @Override
    public String toString() {
        return "AirShip{" + 
                "orbitalModule=" + orbitalModule +
                ", engine=" + engine +
                ", escapeTower=" + escapeTower +
                '}';
    }
}
//軌道艙對象
class OrbitalModule{
    private String name;
    public OrbitalModule(String name) {
        this.name = name;
    }
    public String getName() {
        return name;
    }
    public void setName(String name) {
        this.name = name;
    }

    @Override
    public String toString() {
        return "OrbitalModule{" +
                "name='" + name + '\'' +
                '}';
    }
}
//發動機對象
class Engine {
    private String name;
    public Engine(String name) {
        this.name = name;
    }
    public String getName() {
        return name;
    }
    public void setName(String name) {
        this.name = name;
    }

    @Override
    public String toString() {
        return "Engine{" +
                "name='" + name + '\'' +
                '}';
    }
}
//逃逸塔對象
class EscapeTower{
    private String name;
    public String getName() {
        return name;
    }
    public void setName(String name) {
        this.name = name;
    }
    public EscapeTower(String name) {
        super();
        this.name = name;
    }

    @Override
    public String toString() {
        return "EscapeTower{" +
                "name='" + name + '\'' +
                '}';
    }
}

public class ShipBuilder {
    public static void main(String[] args) {

        AirShipDirector director = new SxtAirshipDirector(new SxtAirShipBuilder());

        AirShip ship = director.directAirShip();

        System.out.println(ship);
    }
}

運行結果:

  • 構建飛天發動機!
  • 構建軌道艙
  • 構建逃逸塔
  • AirShip{orbitalModule=OrbitalModule{name='飛天軌道艙'}, engine=Engine{name='飛天發動機!'}, escapeTower=EscapeTower{name='飛天逃逸塔'}}

建造者模式優點:

  • 易於解耦 :將產品本身與產品創建過程進行解耦,可以使用相同的創建過程來得到不同的產品。也就說細節依賴抽象。
  • 易於精確把控對象的創建 :將複雜產品的創建步驟分解在不同的方法中,使得創建過程更加清晰
  • 易於拓展 :增加新的具體建造者無需修改原有類庫的代碼,易於拓展,符合“開閉原則“。 

建造者模式缺點:

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

當生成的類比較複雜,並且生成的內部對象又相互依賴關係的情況下,可以選擇建造者模式。 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章