【創建型設計模式】建造模式

前言(一些廢話,可以忽略)

  • 這是最後一種創建型設計模式,見名知義,我們需要建造一些東西,這些東西的流程都是一樣的,這樣就可以進行抽象,依賴抽象,擁抱變化,go on
  • PS.部分類實現見文末

解決建房子的問題

  • 我們建房子,不管建什麼類型的房子,都需要和水泥,砌磚,封頂,如果把建房子和這些必要的步驟組合在一起,直接創建出房子對象,當我們需要建不同類型的房子,或者需要增加修改不同類型的建造方式的時候,我們建房子這個操作就會顯得很臃腫。

普通的建造者模式

  • 建造者模式的邏輯很簡單,就是抽象一箇中間緩衝層,這樣就方便了擴展,然後將建造某一個產品的步驟進行封裝,以供統一調用,如下:
/**
 * @program: ade-someproblem
 * @author: cade franklin
 * @create: 2019-12-22 22:20
 **/
public interface HouseBuilder {
    void andCement();//和水泥
    void brickLaying();//砌磚
    void capping();//封頂
    House getHouse();//獲得房子
}
  • 通過實現抽象的建造者來實現具體的某種類型房子的建造
/**
 * 別墅
 * @program: ade-someproblem
 * @author: cade franklin
 * @create: 2019-12-22 22:20
 **/
public class FlatBuilder implements HouseBuilder {
	//這裏可以是聚合 也可以是組合,個人感覺沒有關係
    private Flat flat = new Flat();

    @Override
    public void andCement() {
        System.out.println("FlatBuilder.andCement");
        flat.setName("FLAT");
    }

    @Override
    public void brickLaying() {
        System.out.println("FlatBuilder.brickLaying");
    }

    @Override
    public void capping() {
        System.out.println("FlatBuilder.capping");
    }

    @Override
    public House getHouse() {
        this.andCement();
        this.brickLaying();
        this.capping();
		//flat.setName("FLAT");
        return flat;
    }
}
  • 我們建造的產品,即房子的一種,公寓
/**
 * 公寓
 * @program: ade-someproblem
 * @author: cade franklin
 * @create: 2019-12-22 22:20
 **/
public class Flat implements House{

    private String name;

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

	//也可以將房子抽象出來然後實現之,真正使用的時候看業務場景,我感覺這裏的name還有點畫蛇添足的意思
    @Override
    public String name() {
        return "Flat";
    }
}
  • 最後,通過另外一個指揮類來統一建造我們想要的產品
/**
 * @program: ade-someproblem
 * @author: cade franklin
 * @create: 2019-12-22 22:20
 **/
public class HouseDirector {
    HouseBuilder builder;

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

    public void constract(){
        builder.getHouse();
    }
}
  • 簡單的捋一下,UML圖就出來了,一個Builder接口,具體的建造者ConcreteBuilder聚合一個Product產品實體,我們在使用的時候通過Director聚合的ConcreteBuilder進行房子的建造
    在這裏插入圖片描述

  • 具體的使用如下

/**
 * @program: ade-someproblem
 * @author: cade franklin
 * @create: 2019-12-22 22:20
 **/
public class BuilderMode {
    public static void main(String[] args) {
        HouseBuilder builder = new FlatBuilder();
        HouseDirector director = new HouseDirector(builder);
        House flat = director.constract();
        System.out.println(flat.name());
    }
}
  • 這裏可能會有疑問,怎麼和工廠模式有點類似,他們的區別是啥子呢
  • 仔細分析一下,我們發現,建造者模式關注的產品的構建過程,而工廠模式呢,是關注最終生成的產品結果

變形的建造者模式

  • 個人感覺,變形的建造者模式可能大家使用得更頻繁,至少遇見的次數更多
  • 因爲它有很強的標誌性,在創建對象時,直接通過調用鏈的方式設置屬性
  • 然後最後通過builder()生成我們需要的對象,接下來我們直接看代碼
/**
 * 建造者模式 屬性過多通過調用串的方式對需要的屬性設值
 * @program: ade-someproblem
 * @author: cade franklin
 * @create: 2019-12-22 22:20
 **/
public class ImproveBuilderMode {
    public static void main(String[] args) {
        DemoBuilder builder = new DemoBuilder.MyBuilder().name("sss").builder();
        System.out.println(builder);
    }
}

class DemoBuilder {
    private String name;
    private String address;
    private String hgight;
    
    @Override
    public String toString() {
        return "DemoBuilder{" +
                "name='" + name + '\'' +
                ", address='" + address + '\'' +
                ", hgight='" + hgight + '\'' +
                '}';
    }
    private DemoBuilder() {
    }

    static class MyBuilder {
        private DemoBuilder builder = new DemoBuilder();

        public MyBuilder name(String name) {
            builder.name = name;
            return this;
        }
        public MyBuilder address(String address) {
            builder.address = address;
            return this;
        }
        public MyBuilder hgight(String hgight) {
            builder.hgight = hgight;
            return this;
        }

        public DemoBuilder builder() {
            return builder;
        }
    }
}
  • 在自己寫的時候注意關鍵點,靜態內部類,私有的構造者器即可
  • 此種模式的核心優勢就在多熟悉情況下,我們可以簡潔的設置屬性獲取對象
  • 與普通的建造者異同在哪裏呢?可以注意到主要區別在於結構上,普通的建造者的結構更廣,涉及不同的建造流程,而變形的建造者關注屬性的注入(個人拙見)
  • 如果我們將普通的建造者改爲設置屬性的話,可能就更容易理解了

總結

  • 建造者模式就是這樣的了,關注對象的建造過程,通過抽取共同特點,完成緩衝層的搭建,方便擴展。
  • 如果沒有建造對象時的共同特點(相同的方法),那可能就不太適合建造者模式了
  • 關於普通的建造者模式和變形的建造者模式的區別,一方面是我的代碼例子舉得不恰當,另一方面,我得爲自己辯解一句,設計模式關注的是設計思想,遵循相關原則即可,部分細節不用較真。當然如果你有任何問題,歡迎私信我,我們一起討論,嘻嘻😳

願你不捨愛與自由。

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