瞭解23種設計模式之建造者模式

一,什麼是建造者模式

Builder 模式又叫 建造者模式或者生成器模式。是由GoF 提出的23種設計模式中的一種。

Builder 模式是一種對象創建型模式之一,用來隱藏複合對象的創建過程,它把複合對象的創建過程加以抽象,

通過子類繼承和重載的方式,動態的創建具有複合屬性的對象。

 

二,裝飾模式的結構

 

抽象建造者(builder):描述具體建造者的公共接口,一般用來定義建造細節的方法,並不涉及具體的對象部件的創建。

具體建造者(ConcreteBuilder):描述具體建造者,並實現抽象建造者公共接口。

指揮者(Director):調用具體建造者來創建複雜對象(產品)的各個部分,並按照一定順序(流程)來建造複雜對象。

產品(Product):描述一個由一系列部件組成較爲複雜的對象。

 

三,應用場景,優點,缺點。

應用場景:對象的創建:Builder 模式是爲對象的創建而設計的模式

創建的是一個複合對象:被創建的對象爲了一個具有複合屬性的複合對象

關注對象創建的各部分的創建過程:不同的工廠(這裏指build生成器)對產品屬性有不同的創建方法

優點:

1,產品的建造和表示分離,實現瞭解耦。

2,將複雜產品的創建步驟分解在不通過的方法中,使得創建過程更加清晰。

3,增加新的具體建造者無需修改原有了類庫的代碼,易於拓展,符合“開閉原則“。

缺點:

1、產品必須有共同點,限制了使用範圍。

2、如內部變化複雜,會有很多的建造類,難以維護

四:代碼實現:

1,產品:Product.java

public class House {
    //地板
    private String floor;
    //牆
    private String wall;
    //屋頂
    private String housetop;

    public String getFloor() {
        return floor;
    }

    public void setFloor(String floor) {
        this.floor = floor;
    }

    public String getWall() {
        return wall;
    }

    public void setWall(String wall) {
        this.wall = wall;
    }

    public String getHousetop() {
        return housetop;
    }

    public void setHousetop(String housetop) {
        this.housetop = housetop;
    }
}

2,建造者:Builder.java

public interface HouseBuilder {

    //修地板
    public void makeFloor();

    //修牆
    public void makeWall();

    //修屋頂
    public  void makeHouseTop();

    //返回對象
    public  House createHouse();
    
}

3,具體建造者:ConcreteBuilder.java 

  兩個 不同的建造者

3.1

public class PingFangBuilder implements HouseBuilder {
    House house = new House();

    @Override
    public void makeFloor() {
        house.setFloor("平房");
    }

    @Override
    public void makeWall() {
        house.setWall("牆");
    }

    @Override
    public void makeHouseTop() {
        house.setHousetop("房頂");
    }

    @Override
    public House createHouse() {
         return  house;
    }
}

3.2

public class GongyuBuilder implements HouseBuilder{
    House house = new House();
    @Override
    public void makeFloor() {
        house.setFloor("別墅 ---》地板");
    }

    @Override
    public void makeWall() {
        house.setWall("別墅 ---》牆");
    }

    @Override
    public void makeHouseTop() {
        house.setHousetop("別墅 ---》屋頂");
    }

    @Override
    public House createHouse() {
        return house;
    }
}

4.指揮者:Director.java

public class HouseDirector {

    private HouseBuilder houseBuilder;

    public HouseDirector(HouseBuilder houseBuilder) {
        this.houseBuilder = houseBuilder;
    }

    public House makeHouse(){
        houseBuilder.makeWall();
        houseBuilder.makeHouseTop();
        houseBuilder.makeFloor();
        House house  = houseBuilder.createHouse();
        return  house;
    }

    public HouseBuilder creBuilder(String type){
        try {
            Class houseBuilder  = Class.forName(type);
            return (HouseBuilder)houseBuilder.newInstance();
        } catch (ClassNotFoundException e) {
            e.printStackTrace();
            System.out.println("找不到對象");
        } catch (IllegalAccessException e) {
            e.printStackTrace();
            System.out.println("實例化錯誤");
        } catch (InstantiationException e) {
            e.printStackTrace();
            System.out.println("非法訪問異常");
        }
        return  null;
    }

}

測試:

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

     /*   House house = new House();
        house.setFloor("地板");
        house.setWall("牆");
        house.setHousetop("屋頂");*/

        HouseBuilder houseBuilder = new PingFangBuilder();
        /*houseBuilder.makeHouseTop();
        houseBuilder.makeWall();
        houseBuilder.makeFloor();
        House house  = houseBuilder.createHouse();

        System.out.println(house.getWall());
        System.out.println(house.getHousetop());
        System.out.println(house.getFloor());*/

        HouseDirector houseDirector = new HouseDirector(houseBuilder);
        House house  =  houseDirector.makeHouse();

        System.out.println(house.getWall());
        System.out.println(house.getHousetop());
        System.out.println(house.getFloor());
    }

}

五:總結

將複雜產品的具體屬性 交給不同的 建造者去設計,指揮者 來具體的調用不同的建造者。 而我們只需要跟指揮者說 我要建造什麼樣的產品,指揮者就給我什麼產品。 對產品的分離,實現解耦。使代碼更加符合開閉原則,關閉修改,開放拓展。

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