這段代碼是我在學習了java版的抽象工廠模式后,實現的ES6版抽象工廠,后期大幅修改,加入了策略模式,看起來很多邏輯看似繁瑣,不必要寫這么多,但是為了練習設計模式,所以才這樣做。當所需的工廠種類增多后,以及需要頻繁修改子工廠時,這樣抽象工廠模式與策略模式的結合就會發揮巨大的優勢,后期維護簡單,耦合性低,便於統計子類型等。
/* 使用策略模式,來將具體的工廠類型進行封裝,然后便於后期添加新的工廠,而不用修改原有的代碼
* 只需要寫出新的工廠類,並使用addClass方法進行添加,及可方便的得到工廠,並生產
* 可以通過對factoryList這個實例對象進行查詢,即可知道有哪些工廠類型可以進行工作
*/
// 定義鋼筆廠
class PenFactory{
constructor(penColor){
this.penColor = penColor;
}
produce(penNum){
console.log(`生產了${penNum}只${this.penColor}顏色的筆`);
}
}
// 定義紙廠
class PaperFactory{
constructor(paperColor){
this.paperColor = paperColor;
}
produce(paperNum){
console.log(`生產了${paperNum}張${this.paperColor}顏色的紙`);
}
}
// 定義手機廠
class PhoneFactory{
constructor(weight){
this.weight = weight;
}
produce(num){
console.log(`生產了${num}個${this.weight}重的手機`);
}
}
// 定義工廠列表類,實現抽象工廠模式,以及策略模式結合使用
class FactoryList{
constructor(){
// 用於保存不同的策略名稱,及對應的方案
this.strateges = {};
}
addClass(factoryClass){
// new 后要跟真正的類不能是類名的字符串,這里接收的參數是真正的類,使用它的name屬性獲取類名
this.strateges[factoryClass.name] = function(config){return new factoryClass(config)};
}
getFactory(className,config){
return this.strateges[className].call(null,config);
}
}
var factoryList = new FactoryList();
factoryList.addClass(PhoneFactory); // 這里的Phone是真正的類,不是字符串類名
factoryList.addClass(PenFactory);
factoryList.addClass(PaperFactory);
// NOTE: 這里定義我自己的工廠,由我決定生存哪些產品,以及有什么工廠
var myFactory = {};
var phoneF = factoryList.getFactory('PhoneFactory','500g');
var penF = factoryList.getFactory('PenFactory','紅色');
var paperF = factoryList.getFactory('PaperFactory','A4');
// 這里要綁定那個具體的工廠類,借用this,確保我自己的廠子的某類具體的生產參數不出錯
myFactory.producePhone = phoneF.produce.bind(phoneF);
myFactory.producePen = penF.produce.bind(penF);
myFactory.producePaper = paperF.produce.bind(paperF);
myFactory.producePhone(10); // 生產了10個500g重的手機
myFactory.producePen(20); // 生產了20只紅色顏色的筆
myFactory.producePaper(30); // 生產了30張A4顏色的紙