簡單的工廠模式能夠理解爲解決多個類似的問題;這也是她的優勢;好比以下代碼:node
function CreatePerson(name,age,sex) {
var obj = new Object();
obj.name = name;
obj.age = age;
obj.sex = sex;
obj.sayName = function(){
return this.name;
}
return obj;
}
var p1 = new CreatePerson("longen",'28','男');
var p2 = new CreatePerson("tugenhua",'27','女');
console.log(p1.name); // longen
console.log(p1.age); // 28
console.log(p1.sex); // 男
console.log(p1.sayName()); // longen
console.log(p2.name); // tugenhua
console.log(p2.age); // 27
console.log(p2.sex); // 女
console.log(p2.sayName()); // tugenhua
// 返回都是object 沒法識別對象的類型 不知道他們是哪一個對象的實列
console.log(typeof p1); // object
console.log(typeof p2); // object
console.log(p1 instanceof Object); // true
複製代碼
如上代碼:函數CreatePerson能接受三個參數name,age,sex等參數,能夠無數次調用這個函數,每次返回都會包含三個屬性和一個方法的對象。框架
工廠模式是爲了解決多個相似對象聲明的問題;也就是爲了解決實列化對象產生重複的問題。函數
優勢:能解決多個類似的問題。學習
缺點:不能知道對象識別的問題(對象的類型不知道)。ui
複雜的工廠模式定義是:將其成員對象的實列化推遲到子類中,子類能夠重寫父類接口方法以便建立的時候指定本身的對象類型。this
父類只對建立過程當中的通常性問題進行處理,這些處理會被子類繼承,子類之間是相互獨立的,具體的業務邏輯會放在子類中進行編寫。spa
父類就變成了一個抽象類,可是父類能夠執行子類中相同相似的方法,具體的業務邏輯須要放在子類中去實現;好比我如今開幾個自行車店,那麼每一個店都有幾種型號的自行車出售。咱們如今來使用工廠模式來編寫這些代碼;prototype
父類的構造函數以下:code
// 定義自行車的構造函數
var BicycleShop = function(){};
BicycleShop.prototype = {
constructor: BicycleShop,
/* * 買自行車這個方法 * @param {model} 自行車型號 */
sellBicycle: function(model){
var bicycle = this.createBicycle(mode);
// 執行A業務邏輯
bicycle.A();
// 執行B業務邏輯
bicycle.B();
return bicycle;
},
createBicycle: function(model){
throw new Error("父類是抽象類不能直接調用,須要子類重寫該方法");
}
};
複製代碼
上面是定義一個自行車抽象類來編寫工廠模式的實列,定義了createBicycle這個方法,可是若是直接實例化父類,調用父類中的這個createBicycle方法,會拋出一個error,由於父類是一個抽象類,他不能被實列化,只能經過子類來實現這個方法,實現本身的業務邏輯,下面咱們來定義子類,咱們學會如何使用工廠模式從新編寫這個方法,首先咱們須要繼承父類中的成員,而後編寫子類;以下代碼:cdn
// 定義自行車的構造函數
var BicycleShop = function(name){
this.name = name;
this.method = function(){
return this.name;
}
};
BicycleShop.prototype = {
constructor: BicycleShop,
/* * 買自行車這個方法 * @param {model} 自行車型號 */
sellBicycle: function(model){
var bicycle = this.createBicycle(model);
// 執行A業務邏輯
bicycle.A();
// 執行B業務邏輯
bicycle.B();
return bicycle;
},
createBicycle: function(model){
throw new Error("父類是抽象類不能直接調用,須要子類重寫該方法");
}
};
// 實現原型繼承
function extend(Sub,Sup) {
//Sub表示子類,Sup表示超類
// 首先定義一個空函數
var F = function(){};
// 設置空函數的原型爲超類的原型
F.prototype = Sup.prototype;
// 實例化空函數,並把超類原型引用傳遞給子類
Sub.prototype = new F();
// 重置子類原型的構造器爲子類自身
Sub.prototype.constructor = Sub;
// 在子類中保存超類的原型,避免子類與超類耦合
Sub.sup = Sup.prototype;
if(Sup.prototype.constructor === Object.prototype.constructor) {
// 檢測超類原型的構造器是否爲原型自身
Sup.prototype.constructor = Sup;
}
}
var BicycleChild = function(name){
this.name = name;
// 繼承構造函數父類中的屬性和方法
BicycleShop.call(this,name);
};
// 子類繼承父類原型方法
extend(BicycleChild,BicycleShop);
// BicycleChild 子類重寫父類的方法
BicycleChild.prototype.createBicycle = function(){
var A = function(){
console.log("執行A業務操做");
};
var B = function(){
console.log("執行B業務操做");
};
return {
A: A,
B: B
}
}
var childClass = new BicycleChild("龍恩");
console.log(childClass);
複製代碼
實例化子類,而後打印出該實例, 以下截圖所示:
console.log(childClass.name); // 龍恩// 下面是實例化後 執行父類中的sellBicycle這個方法後會依次調用父類中的A
// 和B方法;A方法和B方法依次在子類中去編寫具體的業務邏輯。
childClass.sellBicycle("mode"); // 打印出 執行A業務操做和執行B業務操做
上面只是"龍恩"自行車這麼一個型號的,若是須要生成其餘型號的自行車的話,能夠編寫其餘子類,工廠模式最重要的優勢是:能夠實現一些相同的方法,這些相同的方法咱們能夠放在父類中編寫代碼,那麼須要實現具體的業務邏輯,那麼能夠放在子類中重寫該父類的方法,去實現本身的業務邏輯;使用專業術語來說的話有2點:第一:弱化對象間的耦合,防止代碼的重複。在一個方法中進行類的實例化,能夠消除重複性的代碼。第二:重複性的代碼能夠放在父類去編寫,子類繼承於父類的全部成員屬性和方法,子類只專一於實現本身的業務邏輯。