前言(一些廢話,可以忽略)
- 這是最後一種創建型設計模式,見名知義,我們需要建造一些東西,這些東西的流程都是一樣的,這樣就可以進行抽象,依賴抽象,擁抱變化,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;
}
}
}
- 在自己寫的時候注意關鍵點,靜態內部類,私有的構造者器即可
- 此種模式的核心優勢就在多熟悉情況下,我們可以簡潔的設置屬性獲取對象
- 與普通的建造者異同在哪裏呢?可以注意到主要區別在於結構上,普通的建造者的結構更廣,涉及不同的建造流程,而變形的建造者關注屬性的注入(個人拙見)
- 如果我們將普通的建造者改爲設置屬性的話,可能就更容易理解了
總結
- 建造者模式就是這樣的了,關注對象的建造過程,通過抽取共同特點,完成緩衝層的搭建,方便擴展。
- 如果沒有建造對象時的共同特點(相同的方法),那可能就不太適合建造者模式了
- 關於普通的建造者模式和變形的建造者模式的區別,一方面是我的代碼例子舉得不恰當,另一方面,我得爲自己辯解一句,設計模式關注的是設計思想,遵循相關原則即可,部分細節不用較真。當然如果你有任何問題,歡迎私信我,我們一起討論,嘻嘻😳
願你不捨愛與自由。