Factory(工廠模式)
資料來源:
目的
建立物件,通常實作為一個Class,或Class 內的靜態方法。
作用為:
對於建立相似的物件,以進行重複性的工作,達到程式碼精簡的目的。
提供一個無需事先知道,用明確型別建立物件的方式。
舉例
我們可以建立一個工廠(披薩店)
這個披薩店有:進行烘烤
這個披薩店有:烤完,運送給客人
今天假設你點了夏威夷披薩,流程:
進行烘烤。
烤完,運送給客人。
今天假設你點了鮪魚披薩,流程:
進行烘烤。
烤完,運送給客人。
重點:將重複的行為給包裝起來,變成一個工廠,很像API。
Code
ES5
資料來源:Alex-JS_Next
const RamenOtaku = function(type) {
if (typeof RamenOtaku[type] !== "function") {
throw {
name: "訂餐失敗",
message: "查無品項"
};
}
return new RamenOtaku[type]();
};
const RamenOtakuShiromaru = function() {
this.name = "Shiromaru Ramen";
this.taste = "good to eat";
};
RamenOtakuShiromaru.extend(RamenOtaku);
RamenOtaku.prototype.eat = function() {
return `${this.name} is ${this.taste}.`;
};
RamenOtaku.shiromaru = RamenOtakuShiromaru;
//RamenOtaku:建立工廠
//RamenOtakuShiromaru:建立產品
//產品為工廠的 extend
//工廠底下建立一個方法
//設定這個工廠底下的shiromaru為RamenOtakuShiromaru
//注意RamenOtakuShiromaru內又有自身的function
//這邊有個Extend函數,是筆者的上課老師自行定義,故在這邊沒有顯示。
ES6
簡單工廠模式
建立相似物件時,進行重複性的工作,達到程式碼精簡
物件或元件涉及高複雜性
須根據不同環境生成物件的時候
處理很多共享屬性的小型物件或元件時
//Definition of class
class User {
constructor(typeOfUser){
this._canEditEverything = false;
if (typeOfUser === "administrator") {
this._canEditEverything = true;
}
} get canEditEverything() { return this._canEditEverything; }
}
//Instatiation
let u1 = new User("normalGuy");
let u2 = new User("administrator");
工廠方法
一個父類別,一個子類別
首先建立一個父類別,內要有一個變數,內也要有一個function
經由子類別覆寫的方式,建立出新物件,並且可以使用父類別的方法
//Class
class User {
constructor(){
this._canEditEverything = false;
}
get canEditEverything() { return this._canEditEverything; }
}
//Sub-class
class Administrator extends User {
constructor() {
super();
this._canEditEverything = true;
}
}
//Instatiation
let u2 = new Administrator();
let result = u2.canEditEverything; //true
抽象工廠
class PorscheCar {
constructor(params) {
this.engine = params.engine;
this.tyreModel = params.tyreModel;
this.gears = params.gears;
}
}
class PorscheCarFactory {
createCar(params) {
return new PorscheCar(params);
}
}
class FerrariCar {
constructor(params) {
this.engine = params.engine;
this.tyreModel = params.tyreModel;
this.gears = params.gears;
this.turbo = params.turbo;
}
}
class FerrariCarFactory {
createCar(params) {
return new FerrariCar(params);
}
}
class CarFactoryImpl {
constructor() {
this.porscheCar = new PorscheCarFactory();
this.ferrariCar = new FerrariCarFactory();
}
getPorsche() {
return this.porscheCar;
}
getFerrari() {
return this.ferrariCar;
}
}
const fact = new CarFactoryImpl();
let params = { engine: "raw", tyreModel: "basic", gears: null };
const concretePorsche = fact.getPorsche().createCar(params);
console.log(concretePorsche);
params = { engine: "rawraw", tyreModel: "basic", gears: null, turbo: true };
const concreteFerrari = fact.getFerrari().createCar(params);
console.log(concreteFerrari.turbo);
優點
創建物件的過程複雜,但我們只需要知道結果就好
構造函數和創建者分離,符合封閉原則
一個使用者想要創建一個物件,只要知道其名稱就好
想增加一個產品,只要擴建一個工廠即可
缺點
添加新產品時,會增加系統複雜度
需要引入抽象層,增加系統的難以理解度
例子
jQuery、Vue非同步組件
Last updated
Was this helpful?