字節(jié)跳動飛書內(nèi)推!
北京、杭州、武漢、廣州、深圳、上海,六大城市等你來投。
感興趣的朋友可以私我咨詢&內(nèi)推,也可以通過鏈接直接投遞!
海量HC,極速響應(yīng),快來和我成為同事吧。
今日頭條、抖音、Tik Tok也可以內(nèi)推~
點擊進入我的博客
建造者模式(Builder Pattern)使用多個簡單的對象一步一步構(gòu)建成一個復(fù)雜的對象。它提供了一種創(chuàng)建對象的最佳方式。
2.6.1 建造者結(jié)構(gòu)

建造者模式
- Builder(抽象建造者):可以是一個抽象類或一個接口,規(guī)范產(chǎn)品對象的各個組成部分的建造。
- ConcreteBuilder(具體建造者):它實現(xiàn)了Builder接口,給出一步一步的創(chuàng)建產(chǎn)品實例的操作,然后提供一個方法返回創(chuàng)建好的復(fù)雜產(chǎn)品對象。
- Product(產(chǎn)品角色):如果是單個產(chǎn)品類,那么就是一個具體的產(chǎn)品;如果是多個產(chǎn)品類,那么就是一個抽象的類或接口。
- ConcreteProduct(具體產(chǎn)品):當(dāng)多個產(chǎn)品類時,繼承抽象Product,也就是具體的要建造的復(fù)雜對象。值得注意的是,這些產(chǎn)品類不一定會有共同的接口。
- Director(指揮者):它復(fù)雜安排復(fù)雜對象的建造次序,指揮者與抽象建造者之間存在關(guān)聯(lián)關(guān)系,可以在Director的方法中調(diào)用建造者對象的部件構(gòu)造與裝配方法,完成建造復(fù)雜對象的任務(wù)。
2.6.2 建造者模式細節(jié)
主要目的
一個產(chǎn)品通常有不同的組成成分作為產(chǎn)品的零件,不同的產(chǎn)品可以有不同的零件,建造產(chǎn)品的過程是建造零件的過程。建造者模式將產(chǎn)品的結(jié)構(gòu)和產(chǎn)品的零件建造過程對外隱藏起來,把對建造過程進行指揮的責(zé)任和具體建造零件的責(zé)任分割開來,達到責(zé)任劃分和封裝的目的。
解決問題
主要解決在開發(fā)過程中,有時需要創(chuàng)建一個復(fù)雜對象,通常由多個部分的子對象構(gòu)成;由于復(fù)雜對象的多樣性,這個復(fù)雜對象的各個部分經(jīng)常面臨著劇烈的變化,但是將它們組合在一起的算法需要保持穩(wěn)定。
使用場景
- 肯德基的產(chǎn)品很多,需要組成“套餐”。
- Java的StringBuilder
省略角色
- 省略抽象建造者:如果只需要一個具體建造者,則可以省略抽象建造者。
- 省略指揮者:可以在具體建造者里邊直接構(gòu)造具體產(chǎn)品。
- 合并具體建造者和具體產(chǎn)品:在產(chǎn)品本身就是自己的建造者。
優(yōu)點
- 良好的封裝性
- 具體建造類之間獨立,擴展性好
缺點
- 如果產(chǎn)品比較多,可能會有很多的建造類。
2.6.3 肯德基套餐案例
public class Waiter {
public static void main(String[] args) {
KFCBuilder builder = new MexicanTwisterBuilder();
builder.buildBeverage();
builder.buildHamburger();
builder.buildSnack();
KFCCombo combo = builder.getCombo();
}
}
// 套餐接口
abstract class KFCCombo {
private String hamburger;
private String beverage;
private String snack;
// getters & setters
}
// 墨西哥雞肉卷套餐
class MexicanTwisterCombo extends KFCCombo {}
// Builder接口
interface KFCBuilder {
void buildHamburger();
void buildBeverage();
void buildSnack();
KFCCombo getCombo();
}
class MexicanTwisterBuilder implements KFCBuilder {
private KFCCombo combo = new MexicanTwisterCombo();
@Override
public void buildHamburger() {
combo.setHamburger("Mexican Twister");
}
@Override
public void buildBeverage() {
combo.setBeverage("Pepsi Cola");
}
@Override
public void buildSnack() {
combo.setSnack("Hot Wings");
}
@Override
public KFCCombo getCombo() {
return combo;
}
}
2.6.4 builder內(nèi)部類
如果一個類有很多屬性,此時為此類寫一個Builder內(nèi)部類,來輔助建造該類。
class Phone {
private String screen;
private String camera;
private String cpu;
private String battery;
public static Builder builder() {
return new Builder();
}
public static class Builder {
private Phone phone = new Phone();
public Builder screen(String screen) {
phone.screen = screen;
return this;
}
public Builder camera(String camera) {
phone.camera = camera;
return this;
}
public Builder cpu(String cpu) {
phone.cpu = cpu;
return this;
}
public Builder battery(String battery) {
phone.battery = battery;
return this;
}
public Phone build() {
return phone;
}
}
}
2.6.5 與其他模式的關(guān)系
抽象工廠模式
- 抽象工廠模式實現(xiàn)對產(chǎn)品家族的創(chuàng)建,一個產(chǎn)品家族是這樣的一系列產(chǎn)品:具有不同分類維度的產(chǎn)品組合,采用抽象工廠模式則是不需要關(guān)心構(gòu)建過程,只關(guān)心什么產(chǎn)品由什么工廠生產(chǎn)即可。
- 而建造者模式則是要求按照規(guī)定建造產(chǎn)品,它的主要目的是通過組裝零配件而產(chǎn)生一個新產(chǎn)品。
- 換言之,抽象工廠模式在更加具體的維度上,而建造模式在一個更加宏觀的維度上。
策略模式
- 事實上建造模式是策略模式的一種特殊情況,這兩種模式的卻別在于用意不同。
- 建造模式適應(yīng)于為客戶端一點一點地建造新的對象。
- 策略模式的目的是為算法提供抽象的接口。