Java設計模式——建造者模式

建造者模式

建造者模式(Builder Pattern)使用多個簡單的對象一步一步構建成一個複雜的對象。這種類型的設計模式屬於建立型模式,它提供了一種建立對象的最佳方式。java

一個 Builder 類會一步一步構造最終的對象。該 Builder 類是獨立於其餘對象的。算法

意圖:將一個複雜的構建與其表示相分離,使得一樣的構建過程能夠建立不一樣的表示。shell

主要解決:主要解決在軟件系統中,有時候面臨着"一個複雜對象"的建立工做,其一般由各個部分的子對象用必定的算法構成;因爲需求的變化,這個複雜對象的各個部分常常面臨着劇烈的變化,可是將它們組合在一塊兒的算法卻相對穩定。設計模式

什麼時候使用:==一些基本部件不會變,而其組合常常變化的時候。==ide

如何解決:將變與不變分離開。ui

優勢:this

  1. 建造者獨立,易擴展。
  2. 便於控制細節風險。

缺點: 設計

​ 1. 產品必須有共同點,範圍有限制。 code

​ 2. 如內部變化複雜,會有不少的建造類。對象

使用場景: 一、須要生成的對象具備複雜的內部結構。 二、須要生成的對象內部屬性自己相互依賴。

注意事項:與工廠模式的區別是:建造者模式更加關注與零件裝配的順序。而工廠更專一於零件的製造過程。

如今須要構建不少車輛,車的組成有車輪、外殼、發動機、方向盤等,每一個組件有不一樣品牌,最後須要根據客戶需求定製不一樣的車。(車的整體組成是同樣的,組成部件變化)

/**
 * @author objcfeng
 * @description 車的實體類
 * @date 2020/11/2
 */
public class Car {
    //車輪
    private String wheel;
    //外殼
    private String shell;
    //發動機
    private String engine;
    //方向盤
    private String steeringWheel;

    @Override
    public String toString() {
        return "Car{" +
                "wheel='" + wheel + '\'' +
                ", Shell='" + shell + '\'' +
                ", engine='" + engine + '\'' +
                ", steeringWheel='" + steeringWheel + '\'' +
                '}';
    }

    public String getWheel() {
        return wheel;
    }

    public void setWheel(String wheel) {
        this.wheel = wheel;
    }

    public String getShell() {
        return shell;
    }

    public void setShell(String shell) {
        this.shell = shell;
    }

    public String getEngine() {
        return engine;
    }

    public void setEngine(String engine) {
        this.engine = engine;
    }

    public String getSteeringWheel() {
        return steeringWheel;
    }

    public void setSteeringWheel(String steeringWheel) {
        this.steeringWheel = steeringWheel;
    }
}
//車的建造者
public abstract class CarBuilder {
    //造車輪的方法,由於實際上車輪多是一個複雜對象
    public abstract void buildWheel();
    //造外殼的方法
    public abstract void buildShell();
    //造引擎的方法
    public abstract void buildEngine();
    //造方向盤的方法
    public abstract void buildSteeringWheel();
    
    public abstract Car getCar();
}

建造者實現類,多個品牌組裝不一樣的組件

/**
 * @author objcfeng
 * @description 奔馳建造者
 * @date 2020/11/2
 */
public class BenzBuilder extends CarBuilder {
    private Car car=new Car();

    @Override
    public void buildWheel() {
        car.setWheel("上好的車輪");
    }

    @Override
    public void buildShell() {
        car.setShell("奔馳外殼");
    }

    @Override
    public void buildEngine() {
        car.setEngine("奔馳產發動機");
    }

    @Override
    public void buildSteeringWheel() {
        car.setSteeringWheel("有奔馳標識的方向盤");
    }

    @Override
    public Car getCar() {
        return car;
    }
}
/**
 * @author objcfeng
 * @description 寶馬建造者
 * @date 2020/11/2
 */
public class BmwBuilder extends CarBuilder {
    private Car car=new Car();

    @Override
    public void buildWheel() {
        car.setWheel("上好的車輪");
    }

    @Override
    public void buildShell() {
        car.setShell("寶馬外殼");
    }

    @Override
    public void buildEngine() {
        car.setEngine("寶馬產發動機");
    }

    @Override
    public void buildSteeringWheel() {
        car.setSteeringWheel("有寶馬標識的方向盤");
    }

    @Override
    public Car getCar() {
        return car;
    }
}

指揮者

/**
 * @author objcfeng
 * @description 指揮者,指導具體構建者如何構建產品,控制調用前後次序,並向調用者返回完整的產品類
 * @date 2020/11/2
 */
public class CarDirector {
    private CarBuilder builder;

    public CarDirector(CarBuilder builder) {
        this.builder = builder;
    }
    public Car build(){
        builder.buildEngine();
        builder.buildShell();
        builder.buildSteeringWheel();
        builder.buildWheel();
        return builder.getCar();
    }
}

使用:

public class Main {
    public static void main(String[] args) {
        CarBuilder builder1=new BmwBuilder();
        CarBuilder builder2=new BenzBuilder();
        CarDirector carDirector = new CarDirector(builder1);
        Car car = carDirector.build();
        System.out.println(car);
    }
}

輸出

Car{wheel='上好的車輪', Shell='寶馬外殼', engine='寶馬產發動機', steeringWheel='有寶馬標識的方向盤'}

咱們發現,在CarBuilder的實現類中,老是有個重寫的getCar方法返回建立好的Car對象,而且CarBuilder的子類老是須要構建一個新的car對象。由於一個car對象只會被一個CarBuilder建立,所以,能夠將car對象提高到CarBuilder抽象類中建立。以下,

//建造者
public abstract class CarBuilder {
    //新增建立一個新的car對象
    protected Car car = new Car();
     //其餘方法不變
    public abstract void buildWheel();
    public abstract void buildShell();
    public abstract void buildEngine();
    public abstract void buildSteeringWheel();
    //修改返回car對象方法
    public Car getCar(){
        return this.car;
    };
}

實現類

/**
 * @author objcfeng
 * @description 寶馬建造者
 * @date 2020/11/2
 */
public class BmwBuilder extends CarBuilder {
    //注意每一個給car對象構建組成部分的方法調用的是父類的car對象
    @Override
    public void buildWheel() {
        super.car.setWheel("上好的車輪");
    }

    @Override
    public void buildShell() {
        super.car.setShell("寶馬外殼");
    }

    @Override
    public void buildEngine() {
        super.car.setEngine("寶馬產發動機");
    }

    @Override
    public void buildSteeringWheel() {
        super.car.setSteeringWheel("有寶馬標識的方向盤");
    }
    
    //子類不須要實現getCar方法
    //    @Override
    //    public Car getCar() {
    //        return car;
    //    }
}

其餘無需改變。

相關文章
相關標籤/搜索