寫在前面
早該更新文章了宴倍,然而最近深陷項(xiàng)(囹)目(圄)张症。為了適配萬惡的IE8
,不得不使用陳舊的框架Ext
鸵贬,從未接觸過俗他,純英文的文檔,心中的苦悶自是不得而知阔逼。因此兆衅,拖拖沓沓,迎來了久違的建造者模式嗜浮。
什么是建造者模式
將一個復(fù)雜對象的構(gòu)建層與其表現(xiàn)層相互分離羡亩,同樣的構(gòu)建過程可以采用不同的表示。
當(dāng)我們創(chuàng)建一個復(fù)雜的對象時危融,我們需要更多的關(guān)心創(chuàng)建這個對象的整個過程畏铆,甚至是創(chuàng)建對象的每一個細(xì)節(jié)。那這個時候专挪,我們使用建造者模式及志,在這個模式中,有一個指揮者寨腔,一個建造者速侈,由指導(dǎo)者來管理建造者,用戶是與指導(dǎo)者聯(lián)系的迫卢,指導(dǎo)者聯(lián)系建造者最后得到產(chǎn)品倚搬。主要用于“分步驟構(gòu)建一個復(fù)雜的對象”。
四要素
1.產(chǎn)品類Product:一般是一個較為復(fù)雜的對象乾蛤,也就是說創(chuàng)建對象的過程比較復(fù)雜每界,一般會有比較多的代碼量。
2.抽象建造者類Builder: 將建造的具體過程交與它的子類來實(shí)現(xiàn)家卖,這樣更容易擴(kuò)展眨层。
3.建造者類ConcreteBuilder: 組建產(chǎn)品;返回組建好的產(chǎn)品上荡。
4.指導(dǎo)類Director: 負(fù)責(zé)調(diào)用適當(dāng)?shù)慕ㄔ煺邅斫M建產(chǎn)品趴樱,指導(dǎo)類一般不與產(chǎn)品類發(fā)生依賴關(guān)系,與指導(dǎo)類直接交互的是建造者類
舉個栗子??
// 產(chǎn)品類
class Car {
constructor() {
this.frame = false;
this.engine = false;
this.wheel = false;
}
}
// 建造者
class CarBuilder extends Car{
constructor(name) {
super();
this.name = name;
}
buildFrame() {
this.frame = true;
console.log('??車框架搭建完畢');
return this;
}
buildEngine() {
this.engine = true;
console.log('??引擎制造完畢');
return this;
}
buildWheel() {
this.wheel = true;
console.log('??車轱轆制造完畢');
return this;
}
build() {
console.log(this.name + '??車拼裝完成?')
return {
name: this.name,
frame: this.frame,
engine: this.engine,
wheel: this.wheel
}
}
}
// 指揮者
class Director {
constructor(builder) {
this.action = (builder) => {
builder.buildFrame();
builder.buildEngine();
builder.buildWheel();
builder.build();
}
}
}
let carBuilder = new CarBuilder('保時捷');
let director = new Director();
director.action(carBuilder)
我們可以看到,一個零件叁征,對應(yīng)會有一個制造該零件的方法纳账,每次都要去寫一個方法,顯得很浪費(fèi)時間捺疼,又多余疏虫。我們可以對此做簡化:
// 產(chǎn)品類
class Car {
constructor() {
this.frame = false;
this.engine = false;
this.wheel = false;
}
}
// 建造者
class CarBuilder extends Car {
constructor(name) {
super();
Object.keys(this).forEach(key => {
const buildName = `build${key
.substring(0, 1)
.toUpperCase()}${key.substring(1)}`;
this[buildName] = () => {
console.log("汽車??零件" + key + "制造完成");
this[key] = true;
};
return this;
});
this.name = name;
}
build() {
console.log(this.name + "??車拼裝完成?");
return {
name: this.name,
frame: this.frame,
engine: this.engine,
wheel: this.wheel
};
}
}
// 指揮者
class Director {
constructor(builder) {
this.action = builder => {
builder.buildFrame();
builder.buildEngine();
builder.buildWheel();
builder.build();
};
}
}
let carBuilder = new CarBuilder("保時捷");
let director = new Director();
director.action(carBuilder);
同樣的,對于build()方法啤呼,我們也可以利用這種方式卧秘,進(jìn)行精簡:
// 產(chǎn)品類
class Car {
constructor() {
this.frame = false;
this.engine = false;
this.wheel = false;
}
}
// 建造者
class CarBuilder extends Car {
constructor(name) {
super();
Object.keys(this).forEach(key => {
const buildName = `build${key
.substring(0, 1)
.toUpperCase()}${key.substring(1)}`;
this[buildName] = () => {
console.log("汽車??零件" + key + "制造完成");
this[key] = true;
};
return this;
});
this.name = name;
}
build() {
console.log(this.name + "??車拼裝完成?");
const keysNoBuilders = Object.keys(this).filter(key => typeof this[key] !== 'function');
return keysNoBuilders.reduce((returnValue, key) => {
return {
...returnValue,
[key]: this[key]
}
}, {})
}
}
// 指揮者
class Director {
constructor(builder) {
this.action = builder => {
for (const key in builder) {
builder.hasOwnProperty(key) &&
typeof builder[key] === "function" &&
builder[key]();
}
builder.build();
};
}
}
let carBuilder = new CarBuilder("保時捷");
let director = new Director();
director.action(carBuilder);
最后
更新不易,且讀且珍惜媳友。??