电脑知识|欧美黑人一区二区三区|软件|欧美黑人一级爽快片淫片高清|系统|欧美黑人狂野猛交老妇|数据库|服务器|编程开发|网络运营|知识问答|技术教程文章 - 好吧啦网

您的位置:首頁(yè)技術(shù)文章
文章詳情頁(yè)

JavaScript設(shè)計(jì)模式--簡(jiǎn)單工廠模式定義與應(yīng)用案例詳解

瀏覽:114日期:2023-10-25 18:24:52

本文實(shí)例講述了JavaScript設(shè)計(jì)模式--簡(jiǎn)單工廠模式定義與應(yīng)用。分享給大家供大家參考,具體如下:

一,介紹

工廠模式創(chuàng)建對(duì)象(視為工廠里的產(chǎn)品)時(shí)無(wú)需指定創(chuàng)建對(duì)象的具體類(lèi)。

工廠模式定義一個(gè)用于創(chuàng)建對(duì)象的接口,這個(gè)接口由子類(lèi)決定實(shí)例化哪一個(gè)類(lèi)。該模式使一個(gè)類(lèi)的實(shí)例化延遲到了子類(lèi)。而子類(lèi)可以重寫(xiě)接口方法以便創(chuàng)建的時(shí)候指定自己的對(duì)象類(lèi)型。

在這里將工廠簡(jiǎn)單分為三種:

(1)簡(jiǎn)單工廠:通過(guò)第三方的類(lèi)完成松耦合的任務(wù)。(2)復(fù)雜工廠:通過(guò)把實(shí)例化的任務(wù)交給子類(lèi)來(lái)完成的,用以到達(dá)松耦合的目的。(3)超級(jí)工廠:通過(guò)eval()來(lái)完成智能工廠。

工廠的目的:在于判斷接口最終用哪個(gè)類(lèi)實(shí)例化(故與接口密不可分)。使用工廠最終達(dá)到的效果是:多態(tài),和類(lèi)與類(lèi)之間的松耦合。

二,正文部分

工廠模式與接口是密不可分的所以我們需要先引入接口文件和繼承類(lèi)文件

(1)接口文件:

//定義一個(gè)靜態(tài)方法來(lái)實(shí)現(xiàn)接口與實(shí)現(xiàn)類(lèi)的直接檢驗(yàn)//靜態(tài)方法不要寫(xiě)出Interface.prototype ,因?yàn)檫@是寫(xiě)到接口的原型鏈上的//我們要把靜態(tài)的函數(shù)直接寫(xiě)到類(lèi)層次上//(1)定義一個(gè)接口類(lèi)var Interface=function (name,methods) {//name:接口名字 if(arguments.length<2){ alert('必須是兩個(gè)參數(shù)') } this.name=name; this.methods=[];//定義一個(gè)空數(shù)組裝載函數(shù)名 for(var i=0;i<methods.length;i++){ if(typeof methods[i]!='string'){ alert('函數(shù)名必須是字符串類(lèi)型'); }else { this.methods.push( methods[i]); } }};Interface.ensureImplement=function (object) { if(arguments.length<2){ throw new Error('參數(shù)必須不少于2個(gè)') return false; } for(var i=1;i<arguments.length;i++){ var inter=arguments[i]; //如果是接口就必須是Interface類(lèi)型 if(inter.constructor!=Interface){ throw new Error('如果是接口類(lèi)的話,就必須是Interface類(lèi)型'); } //判斷接口中的方法是否全部實(shí)現(xiàn) //遍歷函數(shù)集合 for(var j=0;j<inter.methods.length;j++){ var method=inter.methods[j];//接口中所有函數(shù) //object[method]傳入的函數(shù) //最終是判斷傳入的函數(shù)是否與接口中所用函數(shù)匹配 if(!object[method]||typeof object[method]!='function' ){//實(shí)現(xiàn)類(lèi)中必須有方法名字與接口中所用方法名相同throw new Error('實(shí)現(xiàn)類(lèi)中沒(méi)有完全實(shí)現(xiàn)接口中的所有方法') } } }}

(2)繼承文件

/*創(chuàng)建extend函數(shù)為了程序中所有的繼承操作*///subClass:子類(lèi) superClass:超類(lèi)function extend(subClass,superClass) { //1,使子類(lèi)原型屬性等于父類(lèi)的原型屬性 //初始化一個(gè)中間空對(duì)象,目的是為了轉(zhuǎn)換主父關(guān)系 var F = function () {}; F.prototype = superClass.prototype; //2, 讓子類(lèi)繼承F subClass.prototype = new F(); subClass.prototype.constructor = subClass; //3,為子類(lèi)增加屬性 superClass ==》原型鏈的引用 subClass.superClass = superClass.prototype; //4,增加一個(gè)保險(xiǎn),就算你的原型類(lèi)是超類(lèi)(Object)那么也要把你的構(gòu)造函數(shù)級(jí)別降下來(lái) if (superClass.prototype.constructor == Object.prototype.constructor) { superClass.prototype.constructor = superClass; }}

通過(guò)下面的例子,逐步引進(jìn)工廠模式及改進(jìn)工廠模式

1,工廠模式的引入,

(1)創(chuàng)建接口對(duì)象

var Pet=new Interface('Pet',['eat','run','sing','register']);

(2)定義一個(gè)寵物店類(lèi)并在prototype上進(jìn)行擴(kuò)展

var PetShop=function () {} PetShop.prototype={ //出售寵物的方法 sellPet:function (kind) { //寵物對(duì)象 var pet; //寵物種類(lèi) switch (kind){case ’dog’: pet=new Dog();break;case ’cat’: pet=new Cat(); break;case ’pig’: pet=new Pig(); break;default: pet=new Bird(); } //驗(yàn)證接口 Interface.ensureImplement(pet,Pet);//判斷pet對(duì)象是否全部實(shí)現(xiàn)接口Pet里面全部的方法 (對(duì)象,接口) pet.eat(); pet.register(); return pet; } }

(3)分析寵物的一些特點(diǎn)可以將一些公共的部分提取出來(lái)(這里只是簡(jiǎn)單的提取)

//基類(lèi) 有共同的提出來(lái) function basePet() { this.register=function () { document.write('寵物登記...<br>'); } this.eat=function () { document.write('寵物吃飯...<br>'); } }

(4)各個(gè)實(shí)現(xiàn)類(lèi) ---這里是各種動(dòng)物

function Dog() { Dog.superClass.constructor.call(this);//繼承父類(lèi) //實(shí)現(xiàn)接口部分 this.run=function () { document.write('小狗跑......<br>') } this.sing=function () { document.write('小狗唱歌......<br>') } } function Cat() { Cat.superClass.constructor.call(this);//繼承父類(lèi) //實(shí)現(xiàn)接口部分 this.run=function () { document.write('小貓跑......<br>') } this.sing=function () { document.write('小貓唱歌......<br>') } } function Pig() { Pig.superClass.constructor.call(this);//繼承父類(lèi) //實(shí)現(xiàn)接口部分 this.run=function () { document.write('小豬跑......<br>') } this.sing=function () { document.write('小豬唱歌......<br>') } } function Bird() { Bird.superClass.constructor.call(this);//繼承父類(lèi) //實(shí)現(xiàn)接口部分 this.run=function () { document.write('小鳥(niǎo)跑......<br>') } this.sing=function () { document.write('小鳥(niǎo)唱歌......<br>') } }

(5)各個(gè)實(shí)現(xiàn)類(lèi)繼承基類(lèi)

//繼承extend(Dog,basePet);extend(Cat,basePet);extend(Pig,basePet);extend(Bird,basePet);

(6)創(chuàng)建寵物的開(kāi)始賣(mài)寵物

var newPetShop=new PetShop(); var flowerPig=newPetShop.sellPet('pig'); flowerPig.run();

結(jié)果為:

JavaScript設(shè)計(jì)模式--簡(jiǎn)單工廠模式定義與應(yīng)用案例詳解

總結(jié)一下,上述好像沒(méi)怎么體現(xiàn)有關(guān)工廠之類(lèi)的,我們應(yīng)該注意到這么一個(gè)問(wèn)題就是:當(dāng)需要增加一個(gè)新品種寵物時(shí),我們需要修改 ’寵物店類(lèi)’,耦合度較高。

為了解決這個(gè)問(wèn)題我們使用簡(jiǎn)單工廠模式來(lái)解決。

2,簡(jiǎn)單工廠模式(針對(duì)上述的改進(jìn))

(1)接口文件與繼承文件的的引入 同上面

(2)靜態(tài)工廠

//使用工廠方式創(chuàng)建寵物對(duì)象 // 靜態(tài)工廠 var factoryPet={ //出售寵物的方法 getPet:function (kind) { //寵物對(duì)象 var pet; //寵物種類(lèi) switch (kind){case ’dog’: pet=new Dog(); break;case ’cat’: pet=new Cat(); break;case ’pig’: pet=new Pig(); break;default: pet=new Bird(); } //驗(yàn)證接口 Interface.ensureImplement(pet,Pet);//判斷pet對(duì)象是否全部實(shí)行接口Pet里面全部的方法 return pet; } }

(3)利用工廠創(chuàng)建寵物店對(duì)象

var factoryPetShop=function () {} factoryPetShop.prototype={ getPet:function (kind) { var pet=factoryPet.getPet(kind); pet.eat(); pet.register(); return pet; } }

(4)從寵物店購(gòu)買(mǎi)寵物實(shí)現(xiàn)

var newPetShop=new factoryPetShop(); var flowerCat=newPetShop.getPet('cat'); flowerCat.sing();

(5)使用簡(jiǎn)單工廠實(shí)現(xiàn)的全部代碼(數(shù)字標(biāo)號(hào)表示其思考的先后順序)

(function () { //(2)接口調(diào)用 var Pet=new Interface('Pet',['eat','run','sing','register']); //(3)基類(lèi) 分析后有共同的提出來(lái)作為基類(lèi) function basePet() { this.register=function () { document.write('寵物登記。。。。<br>'); } this.eat=function () { document.write('寵物吃飯。。。。<br>'); } } //(4)實(shí)現(xiàn)類(lèi) 繼承基類(lèi)+接口實(shí)現(xiàn) function Dog() { Dog.superClass.constructor.call(this);//繼承父類(lèi) //實(shí)現(xiàn)接口 this.run=function () { document.write('小狗跑......<br>') } this.sing=function () { document.write('小狗唱歌......<br>') } } function Cat() { Cat.superClass.constructor.call(this);//繼承父類(lèi) //實(shí)現(xiàn)接口 this.run=function () { document.write('小貓跑......<br>') } this.sing=function () { document.write('小貓唱歌......<br>') } } function Pig() { Pig.superClass.constructor.call(this);//繼承父類(lèi) //實(shí)現(xiàn)接口 this.run=function () { document.write('小豬跑......<br>') } this.sing=function () { document.write('小豬唱歌......<br>') } } function Bird() { Bird.superClass.constructor.call(this);//繼承父類(lèi) //實(shí)現(xiàn)接口 this.run=function () { document.write('小鳥(niǎo)跑......<br>') } this.sing=function () { document.write('小鳥(niǎo)唱歌......<br>') } } //繼承 extend(Dog,basePet); extend(Cat,basePet); extend(Pig,basePet); extend(Bird,basePet); //(1)使用工廠方式創(chuàng)建寵物對(duì)象 // 靜態(tài)工廠 var factoryPet={ //出售寵物的方法 getPet:function (kind) { //寵物對(duì)象 var pet; //寵物種類(lèi) switch (kind){case ’dog’: pet=new Dog(); break;case ’cat’: pet=new Cat(); break;case ’pig’: pet=new Pig(); break;default: pet=new Bird(); } //驗(yàn)證接口 Interface.ensureImplement(pet,Pet);//判斷pet對(duì)象是否全部實(shí)行接口Pet里面全部的方法 return pet; } } //(5)利用工廠的寵物店對(duì)象(寵物店買(mǎi)寵物) var factoryPetShop=function () {} factoryPetShop.prototype={ getPet:function (kind) { var pet=factoryPet.getPet(kind); pet.eat(); pet.register(); return pet; } }//(6)從寵物店購(gòu)買(mǎi)寵物 var newPetShop=new factoryPetShop();//寵物工廠 var flowerCat=newPetShop.getPet('cat');//從寵物工廠中得到寵物 flowerCat.sing();})()

總結(jié)一下,上述看似完美,但是任有問(wèn)題存在:比如說(shuō):張三的寵物店想賣(mài)哈士奇,李四的寵物店想賣(mài)鳥(niǎo)時(shí),這樣的話,寵物都是通過(guò)一個(gè)工廠生產(chǎn)的,并不一定滿足各個(gè)賣(mài)家的需求。

所以我們需要根據(jù)各個(gè)廠家的需求,有不同的工廠,各個(gè)賣(mài)家可以根據(jù)自己需求使用不同的工廠(其實(shí)是利用不同子類(lèi)實(shí)現(xiàn)各自合適的工廠),用于滿足每個(gè)寵物店的不同。

于是我們有了復(fù)雜的工廠用來(lái)解決該問(wèn)題。

3,復(fù)雜工廠:通過(guò)把實(shí)例化的任務(wù)交給子類(lèi)來(lái)完成的,用以到達(dá)松耦合的目的。

此處同樣是根據(jù)上述進(jìn)行改進(jìn)的,還是簡(jiǎn)單的說(shuō)明一下實(shí)現(xiàn)過(guò)程

(1)在html中將接口文件的引進(jìn),代碼為

//定義一個(gè)靜態(tài)方法來(lái)實(shí)現(xiàn)接口與實(shí)現(xiàn)類(lèi)的直接檢驗(yàn)//靜態(tài)方法不要寫(xiě)出Interface.prototype ,因?yàn)檫@是寫(xiě)到接口的原型鏈上的//我們要把靜態(tài)的函數(shù)直接寫(xiě)到類(lèi)層次上//定義一個(gè)接口類(lèi)var Interface=function (name,methods) {//name:接口名字 if(arguments.length<2){ alert('必須是兩個(gè)參數(shù)') } this.name=name; this.methods=[];//定義一個(gè)空數(shù)組裝載函數(shù)名 for(var i=0;i<methods.length;i++){ if(typeof methods[i]!='string'){ alert('函數(shù)名必須是字符串類(lèi)型'); }else { this.methods.push( methods[i]); } }};Interface.ensureImplement=function (object) { if(arguments.length<2){ throw new Error('參數(shù)必須不少于2個(gè)') return false; } for(var i=1;i<arguments.length;i++){ var inter=arguments[i]; //如果是接口就必須是Interface類(lèi)型 if(inter.constructor!=Interface){ throw new Error('如果是接口類(lèi)的話,就必須是Interface類(lèi)型'); } //判斷接口中的方法是否全部實(shí)現(xiàn) //遍歷函數(shù)集合 for(var j=0;j<inter.methods.length;j++){ var method=inter.methods[j];//接口中所有函數(shù) //object[method]傳入的函數(shù) //最終是判斷傳入的函數(shù)是否與接口中所用函數(shù)匹配 if(!object[method]||typeof object[method]!='function' ){//實(shí)現(xiàn)類(lèi)中必須有方法名字與接口中所用方法名相同throw new Error('實(shí)現(xiàn)類(lèi)中沒(méi)有完全實(shí)現(xiàn)接口中的所有方法') } } }}

(2)在html中將繼承文件引入,代碼如下,

/*創(chuàng)建extend函數(shù)為了程序中所有的繼承操作*///subClass:子類(lèi) superClass:超類(lèi)function extend(subClass,superClass) { //1,使子類(lèi)原型屬性等于父類(lèi)的原型屬性 //初始化一個(gè)中間空對(duì)象,目的是為了轉(zhuǎn)換主父關(guān)系 var F = function () {}; F.prototype = superClass.prototype; //2, 讓子類(lèi)繼承F subClass.prototype = new F(); subClass.prototype.constructor = subClass; //3,為子類(lèi)增加屬性 superClass ==》原型鏈的引用 subClass.superClass = superClass.prototype; //4,增加一個(gè)保險(xiǎn),就算你的原型類(lèi)是超類(lèi)(Object)那么也要把你的構(gòu)造函數(shù)級(jí)別降下來(lái) if (superClass.prototype.constructor == Object.prototype.constructor) { superClass.prototype.constructor = superClass; }}

(3)分析各個(gè)類(lèi)提出相同的部分作為基類(lèi),基類(lèi)代碼如下

//基類(lèi) 分析后有共同的提出來(lái)作為基類(lèi) function basePet() { this.register=function () { document.write('寵物登記。。。。<br>'); }; this.eat=function () { document.write('寵物吃飯。。。。<br>'); } }

(4)各個(gè)具體的實(shí)現(xiàn)類(lèi):繼承基類(lèi)+接口實(shí)現(xiàn)

//各個(gè)寵物類(lèi)(實(shí)現(xiàn)類(lèi)) 繼承基類(lèi)+接口實(shí)現(xiàn) function Dog() { Dog.superClass.constructor.call(this);//繼承父類(lèi) //實(shí)現(xiàn)接口 this.run=function () { document.write('小狗跑......<br>') } this.sing=function () { document.write('小狗唱歌......<br>') } } function Cat() { Cat.superClass.constructor.call(this);//繼承父類(lèi) //實(shí)現(xiàn)接口 this.run=function () { document.write('小貓跑......<br>') } this.sing=function () { document.write('小貓唱歌......<br>') } } function Pig() { Pig.superClass.constructor.call(this);//繼承父類(lèi) //實(shí)現(xiàn)接口 this.run=function () { document.write('小豬跑......<br>') } this.sing=function () { document.write('小豬唱歌......<br>') } } function Bird() { Bird.superClass.constructor.call(this);//繼承父類(lèi) //實(shí)現(xiàn)接口 this.run=function () { document.write('小鳥(niǎo)跑......<br>') }; this.sing=function () { document.write('小鳥(niǎo)唱歌......<br>') } }

(5)實(shí)現(xiàn)類(lèi)與基類(lèi)的繼承實(shí)現(xiàn),代碼如下(調(diào)用extend())

extend(Dog,basePet);//動(dòng)物狗繼承基類(lèi) extend(Cat,basePet); extend(Pig,basePet); extend(Bird,basePet);

(6)將商店抽取出來(lái),做成抽象類(lèi),代碼如下

//把核心商店抽取出來(lái) var petShop=function () {}; petShop.prototype={//模擬抽象類(lèi) 需要被子類(lèi)覆蓋 getPet:function (kind){var pet=this.getpet(kind);pet.eat();pet.register();return pet; }, getpet:function (model){ throw new Error('該類(lèi)是抽象類(lèi),不能實(shí)例化') } };

(7)利用子類(lèi)來(lái)滿足各個(gè)商家的不同類(lèi)型寵物店的實(shí)現(xiàn) ,代碼如下

//利用子類(lèi)來(lái)滿足之前的需求(多態(tài)) var oneShop=function () { } extend(oneShop,petShop);//繼承 //覆寫(xiě)方法 oneShop.prototype.getpet=function (model) { //寵物對(duì)象 var pet; //寵物種類(lèi) switch (model){ case ’dog’: pet=new Dog(); break; default: pet=new Bird(); } //驗(yàn)證接口 Interface.ensureImplement(pet,Pet);//判斷pet對(duì)象是否全部實(shí)行接口Pet里面全部的方法 pet.eat(); pet.register(); return pet; };

同上,這個(gè)也是一個(gè)不同的子類(lèi)

twoShop=function () {}; extend(twoShop,petShop);//商店的繼承 //覆寫(xiě)方法 twoShop.prototype.getPet=function (model) { //寵物對(duì)象 var pet; //寵物種類(lèi) switch (kind){ case ’pig’: pet=new Pig(); break; default: pet=new Bird(); } //驗(yàn)證接口 Interface.ensureImplement(pet,Pet);//判斷pet對(duì)象是否全部實(shí)行接口Pet里面全部的方法 pet.eat(); pet.register(); return pet; };

(8) 使用,實(shí)質(zhì)是子類(lèi)對(duì)父類(lèi)的實(shí)例化

這里實(shí)現(xiàn)其中一個(gè)寵物店,另外一個(gè)同理。

//子類(lèi)對(duì)父類(lèi)的實(shí)例化 var jim=new oneShop(); var pig= jim.getpet('dog'); pig.run(); pig.sing()

(9)上述代碼綜合在一起為,代碼如下

(function () { //(2)接口調(diào)用 var Pet=new Interface('Pet',['eat','run','sing','register']); //(1)基類(lèi) 分析后有共同的提出來(lái)作為基類(lèi) function basePet() { this.register=function () { document.write('寵物登記。。。。<br>'); }; this.eat=function () { document.write('寵物吃飯。。。。<br>'); } } //(3)實(shí)現(xiàn)類(lèi) 繼承基類(lèi)+接口實(shí)現(xiàn) function Dog() { Dog.superClass.constructor.call(this);//繼承父類(lèi) //實(shí)現(xiàn)接口 this.run=function () { document.write('小狗跑......<br>') } this.sing=function () { document.write('小狗唱歌......<br>') } } function Cat() { Cat.superClass.constructor.call(this);//繼承父類(lèi) //實(shí)現(xiàn)接口 this.run=function () { document.write('小貓跑......<br>') } this.sing=function () { document.write('小貓唱歌......<br>') } } function Pig() { Pig.superClass.constructor.call(this);//繼承父類(lèi) //實(shí)現(xiàn)接口 this.run=function () { document.write('小豬跑......<br>') } this.sing=function () { document.write('小豬唱歌......<br>') } } function Bird() { Bird.superClass.constructor.call(this);//繼承父類(lèi) //實(shí)現(xiàn)接口 this.run=function () { document.write('小鳥(niǎo)跑......<br>') }; this.sing=function () { document.write('小鳥(niǎo)唱歌......<br>') } } //繼承 extend(Dog,basePet);//寵物的繼承 extend(Cat,basePet); extend(Pig,basePet); extend(Bird,basePet); //(4)把核心商店抽取出來(lái) var petShop=function () {}; petShop.prototype={//模擬抽象類(lèi) 需要被子類(lèi)覆蓋 getPet:function (kind){var pet=this.getpet(kind);pet.eat();pet.register();return pet; }, getpet:function (model){ throw new Error('該類(lèi)是抽象類(lèi),不能實(shí)例化') } }; //(5)商店1 利用子類(lèi)來(lái)滿足之前的需求(多態(tài)) var oneShop=function () { } extend(oneShop,petShop);//繼承 //覆寫(xiě)方法 oneShop.prototype.getpet=function (model) { //寵物對(duì)象 var pet; //寵物種類(lèi) switch (model){ case ’dog’: pet=new Dog(); break; default: pet=new Bird(); } //驗(yàn)證接口 Interface.ensureImplement(pet,Pet);//判斷pet對(duì)象是否全部實(shí)行接口Pet里面全部的方法 pet.eat(); pet.register(); return pet; }; //(5)商店2 twoShop=function () {}; extend(twoShop,petShop);//商店的繼承 //覆寫(xiě)方法 twoShop.prototype.getPet=function (model) { //寵物對(duì)象 var pet; //寵物種類(lèi) switch (kind){ case ’pig’: pet=new Pig(); break; default: pet=new Bird(); } //驗(yàn)證接口 Interface.ensureImplement(pet,Pet);//判斷pet對(duì)象是否全部實(shí)行接口Pet里面全部的方法 pet.eat(); pet.register(); return pet; }; //(6)使用 子類(lèi)對(duì)父類(lèi)的實(shí)例化 var jim=new oneShop();//開(kāi)寵物店 var pig= jim.getpet('dog');//從寵物店得到寵物 pig.run();//寵物功能 pig.sing()})();

注:代碼中的注釋編號(hào)表示其大概思考過(guò)程及實(shí)現(xiàn)順序。

總結(jié)一下,在該個(gè)模式中主要體現(xiàn)在多態(tài)多一點(diǎn)。現(xiàn)在我們將前面的各種綜合在一起使用JavaScript的eval()做一個(gè)智能化的工廠。

4,通過(guò)eval()實(shí)現(xiàn)智能化工廠

(1)接口文件和繼承文件的引入,如上述的一模一樣,這里將不再重復(fù)貼代碼了,直接開(kāi)始我們的新東西吧。

(2)接口調(diào)用

var Pet=new Interface('Pet',['eat','run','sing','register']);

(3)將相同部分提取出來(lái)(簡(jiǎn)單的提取)

//基類(lèi) 分析后有共同的提出來(lái)作為基類(lèi) function basePet() { this.register=function () { document.write('寵物登記。。。。<br>'); }; this.eat=function () { document.write('寵物吃飯。。。。<br>'); } }

(4)各動(dòng)物類(lèi)

//實(shí)現(xiàn)類(lèi) 繼承基類(lèi)+接口實(shí)現(xiàn) function Dog() { Dog.superClass.constructor.call(this);//繼承父類(lèi) //實(shí)現(xiàn)接口 this.run=function () { document.write('小狗跑......<br>') } this.sing=function () { document.write('小狗唱歌......<br>') } } function Cat() { Cat.superClass.constructor.call(this);//繼承父類(lèi) //實(shí)現(xiàn)接口 this.run=function () { document.write('小貓跑......<br>') } this.sing=function () { document.write('小貓唱歌......<br>') } } function Pig() { Pig.superClass.constructor.call(this);//繼承父類(lèi) //實(shí)現(xiàn)接口 this.run=function () { document.write('小豬跑......<br>') } this.sing=function () { document.write('小豬唱歌......<br>') } } function Bird() { Bird.superClass.constructor.call(this);//繼承父類(lèi) //實(shí)現(xiàn)接口 this.run=function () { document.write('小鳥(niǎo)跑......<br>') }; this.sing=function () { document.write('小鳥(niǎo)唱歌......<br>') } }

(5)實(shí)現(xiàn)各動(dòng)物類(lèi)繼承基類(lèi)

//繼承 extend(Dog,basePet); extend(Cat,basePet); extend(Pig,basePet); extend(Bird,basePet);

(6)將商店核心抽取出來(lái),做成一個(gè)抽象類(lèi),代碼如下,

var petShop=function () {}; petShop.prototype={//模擬抽象類(lèi) 需要被子類(lèi)覆蓋 getPet:function (kind){ var pet=this.getpet(kind); pet.eat(); pet.register(); return pet; }, getpet:function (model){ throw new Error('該類(lèi)是抽象類(lèi),不能實(shí)例化') } };//這里是做成抽象類(lèi)其中的getpet方法是通過(guò)子類(lèi)實(shí)現(xiàn)的。

(7)做一個(gè)智能工廠

//(5)智能工廠 只負(fù)責(zé)生成寵物 var PetFactory={ sellPet:function (kind) { var pet; pet=eval('new '+kind+'()'); Interface.ensureImplement(pet,Pet);//判斷pet對(duì)象是否全部實(shí)行接口Pet里面全部的方法 return pet; } }

(8)利用子類(lèi)來(lái)滿足各個(gè)商家的不同類(lèi)型寵物店的實(shí)現(xiàn) ,代碼如下

其中一個(gè)子類(lèi)

//利用子類(lèi)來(lái)滿足各個(gè)商家的不同類(lèi)型寵物店的實(shí)現(xiàn) (多態(tài)) var oneShop=function () { }; extend(oneShop,petShop);//繼承 //覆寫(xiě)方法 oneShop.prototype.getpet=function (model) { //寵物對(duì)象 var pet=null; //寵物種類(lèi) var pets=['Dog','Cat','Bird'];//商店自己擁有的寵物 寵物貨架 for(v in pets){//循環(huán)出索引 if(pets[v]==model){//model是我們自己傳遞過(guò)來(lái)需要?jiǎng)?chuàng)建的寵物 pet=PetFactory.sellPet(model);//驗(yàn)證接口 Interface.ensureImplement(pet,Pet);//判斷pet對(duì)象是否全部實(shí)行接口Pet里面全部的方法pet.eat();pet.register();break; } } return pet;

另一個(gè)子類(lèi)

//(商店2)利用子類(lèi)來(lái)滿足各個(gè)商家的不同類(lèi)型寵物店的實(shí)現(xiàn) (多態(tài)) twoShop=function () {}; extend(twoShop,petShop);//商店的繼承 //覆寫(xiě)方法 twoShop.prototype.getPet=function (model) { //寵物對(duì)象 var pet=null; //寵物種類(lèi) var pets=['Pig'];//商店自己擁有的寵物 for(v in pets){//循環(huán)出索引 if(pets[v]==model){pet=PetFactory.sellPet(model);//驗(yàn)證接口Interface.ensureImplement(pet,Pet);//判斷pet對(duì)象是否全部實(shí)行接口Pet里面全部的方法pet.eat();pet.register();break; } } return pet; };

(9)實(shí)現(xiàn)開(kāi)寵物店賣(mài)寵物

這里我們來(lái)開(kāi)第二個(gè)商店,賣(mài)Pig

var shop=new twoShop();//創(chuàng)建商店 var pet=shop.getPet('Pig');//從商店中得到寵物 pet.run();//寵物的功能

(10)智能化工廠的代碼

(function () { //(1)接口調(diào)用 var Pet=new Interface('Pet',['eat','run','sing','register']); //(2)基類(lèi) 分析后有共同的提出來(lái)作為基類(lèi) function basePet() { this.register=function () { document.write('寵物登記。。。。<br>'); }; this.eat=function () { document.write('寵物吃飯。。。。<br>'); } } //(3)各個(gè)動(dòng)物類(lèi)(實(shí)現(xiàn)類(lèi)) 繼承基類(lèi)+接口實(shí)現(xiàn) function Dog() { Dog.superClass.constructor.call(this);//繼承父類(lèi) //實(shí)現(xiàn)接口 this.run=function () { document.write('小狗跑......<br>') } this.sing=function () { document.write('小狗唱歌......<br>') } } function Cat() { Cat.superClass.constructor.call(this);//繼承父類(lèi) //實(shí)現(xiàn)接口 this.run=function () { document.write('小貓跑......<br>') } this.sing=function () { document.write('小貓唱歌......<br>') } } function Pig() { Pig.superClass.constructor.call(this);//繼承父類(lèi) //實(shí)現(xiàn)接口 this.run=function () { document.write('小豬跑......<br>') } this.sing=function () { document.write('小豬唱歌......<br>') } } function Bird() { Bird.superClass.constructor.call(this);//繼承父類(lèi) //實(shí)現(xiàn)接口 this.run=function () { document.write('小鳥(niǎo)跑......<br>') }; this.sing=function () { document.write('小鳥(niǎo)唱歌......<br>') } } //繼承 extend(Dog,basePet); extend(Cat,basePet); extend(Pig,basePet); extend(Bird,basePet); //(4)把核心商店抽取出來(lái) var petShop=function () {}; petShop.prototype={//模擬抽象類(lèi) 需要被子類(lèi)覆蓋 getPet:function (kind){ var pet=this.getpet(kind); pet.eat(); pet.register(); return pet; }, getpet:function (model){ throw new Error('該類(lèi)是抽象類(lèi),不能實(shí)例化') } }; //(5)智能工廠 只負(fù)責(zé)生成寵物 var PetFactory={ sellPet:function (kind) { var pet; pet=eval('new '+kind+'()'); Interface.ensureImplement(pet,Pet);//判斷pet對(duì)象是否全部實(shí)行接口Pet里面全部的方法 return pet; } } //(6)(商店1)利用子類(lèi)來(lái)滿足各個(gè)商家的不同類(lèi)型寵物店的實(shí)現(xiàn) (多態(tài)) var oneShop=function () { }; extend(oneShop,petShop);//繼承 //覆寫(xiě)方法 oneShop.prototype.getpet=function (model) { //寵物對(duì)象 var pet=null; //寵物種類(lèi) var pets=['Dog','Cat','Bird'];//商店自己擁有的寵物 寵物貨架 for(v in pets){//循環(huán)出索引 if(pets[v]==model){//model是我們自己傳遞過(guò)來(lái)需要?jiǎng)?chuàng)建的寵物 pet=PetFactory.sellPet(model);//驗(yàn)證接口 Interface.ensureImplement(pet,Pet);//判斷pet對(duì)象是否全部實(shí)行接口Pet里面全部的方法pet.eat();pet.register();break; } } return pet; }; //(商店2)利用子類(lèi)來(lái)滿足各個(gè)商家的不同類(lèi)型寵物店的實(shí)現(xiàn) (多態(tài)) twoShop=function () {}; extend(twoShop,petShop);//商店的繼承 //覆寫(xiě)方法 twoShop.prototype.getPet=function (model) { //寵物對(duì)象 var pet=null; //寵物種類(lèi) var pets=['Pig'];//商店自己擁有的寵物 for(v in pets){//循環(huán)出索引 if(pets[v]==model){pet=PetFactory.sellPet(model);//驗(yàn)證接口Interface.ensureImplement(pet,Pet);//判斷pet對(duì)象是否全部實(shí)行接口Pet里面全部的方法pet.eat();pet.register();break; } } return pet; };//(7)開(kāi)寵物店賣(mài)寵物 var shop=new twoShop(); var pet=shop.getPet('Pig'); pet.run();})();

總結(jié)一下,該種智能化工廠的特點(diǎn)體現(xiàn)在我們需要什么寵物店時(shí),我們可以直接通過(guò)智能化工廠創(chuàng)建。很完美。

3,工廠模式的使用場(chǎng)景

1.需要根據(jù)不同參數(shù)產(chǎn)生不同實(shí)例,這些實(shí)例有一些共性的場(chǎng)景

2.使用者只需要使用產(chǎn)品,不需要知道產(chǎn)品的創(chuàng)建細(xì)節(jié)

注意:除非是適用場(chǎng)景,否則不可濫用工廠模式,會(huì)造成代碼的復(fù)雜度。

4.簡(jiǎn)單工廠模式優(yōu)點(diǎn)

1.工廠類(lèi)集中了所有對(duì)象的創(chuàng)建,便于對(duì)象創(chuàng)建的統(tǒng)一管理

2.對(duì)象的使用者僅僅是使用產(chǎn)品,實(shí)現(xiàn)了單一職責(zé)

3.便于擴(kuò)展,如果新增了一種業(yè)務(wù),只需要增加相關(guān)的業(yè)務(wù)對(duì)象類(lèi)和工廠類(lèi)中的生產(chǎn)業(yè)務(wù)對(duì)象的方法,不需要修改其他的地方。

感興趣的朋友可以使用在線HTML/CSS/JavaScript代碼運(yùn)行工具:http://tools.jb51.net/code/HtmlJsRun測(cè)試上述代碼運(yùn)行效果。

更多關(guān)于JavaScript相關(guān)內(nèi)容感興趣的讀者可查看本站專(zhuān)題:《javascript面向?qū)ο笕腴T(mén)教程》、《JavaScript錯(cuò)誤與調(diào)試技巧總結(jié)》、《JavaScript數(shù)據(jù)結(jié)構(gòu)與算法技巧總結(jié)》、《JavaScript遍歷算法與技巧總結(jié)》及《JavaScript數(shù)學(xué)運(yùn)算用法總結(jié)》

希望本文所述對(duì)大家JavaScript程序設(shè)計(jì)有所幫助。

標(biāo)簽: JavaScript
相關(guān)文章:
主站蜘蛛池模板: 济南冷库安装-山东冷库设计|建造|冷库维修-山东齐雪制冷设备有限公司 | BESWICK球阀,BESWICK接头,BURKERT膜片阀,美国SEL继电器-东莞市广联自动化科技有限公司 | 三佳互联一站式网站建设服务|网站开发|网站设计|网站搭建服务商 赛默飞Thermo veritiproPCR仪|ProFlex3 x 32PCR系统|Countess3细胞计数仪|371|3111二氧化碳培养箱|Mirco17R|Mirco21R离心机|仟诺生物 | 杰福伦_磁致伸缩位移传感器_线性位移传感器-意大利GEFRAN杰福伦-河南赉威液压科技有限公司 | 空心明胶胶囊|植物胶囊|清真胶囊|浙江绿键胶囊有限公司欢迎您! | 航空连接器,航空插头,航空插座,航空接插件,航插_深圳鸿万科 | 体视显微镜_荧光生物显微镜_显微镜报价-微仪光电生命科学显微镜有限公司 | 可程式恒温恒湿试验箱|恒温恒湿箱|恒温恒湿试验箱|恒温恒湿老化试验箱|高低温试验箱价格报价-广东德瑞检测设备有限公司 | 螺纹三通快插接头-弯通快插接头-宁波舜驰气动科技有限公司 | 工业设计,人工智能,体验式3D展示的智能技术交流服务平台-纳金网 J.S.Bach 圣巴赫_高端背景音乐系统_官网 | 灰板纸、灰底白、硬纸板等纸品生产商-金泊纸业 | 热回收盐水机组-反应釜冷水机组-高低温冷水机组-北京蓝海神骏科技有限公司 | 净水器代理,净水器招商,净水器加盟-FineSky德国法兹全屋净水 | 酒吧霸屏软件_酒吧霸屏系统,酒吧微上墙,夜场霸屏软件,酒吧点歌软件,酒吧互动游戏,酒吧大屏幕软件系统下载 | 煤机配件厂家_刮板机配件_链轮轴组_河南双志机械设备有限公司 | 手持气象站_便携式气象站_农业气象站_负氧离子监测站-山东万象环境 | 阀门智能定位器_电液动执行器_气动执行机构-赫尔法流体技术(北京)有限公司 | 保定市泰宏机械制造厂-河北铸件厂-铸造厂-铸件加工-河北大件加工 | OpenI 启智 新一代人工智能开源开放平台 | 全屋整木定制-橱柜,家具定制-四川峨眉山龙马木业有限公司 | 膜结构车棚|上海膜结构车棚|上海车棚厂家|上海膜结构公司 | Copeland/谷轮压缩机,谷轮半封闭压缩机,谷轮涡旋压缩机,型号规格,技术参数,尺寸图片,价格经销商 CTP磁天平|小电容测量仪|阴阳极极化_双液系沸点测定仪|dsj电渗实验装置-南京桑力电子设备厂 | 香蕉筛|直线|等厚|弧形|振动筛|香蕉筛厂家-洛阳隆中重工 | 广州番禺搬家公司_天河黄埔搬家公司_企业工厂搬迁_日式搬家_广州搬家公司_厚道搬迁搬家公司 | MVR蒸发器厂家-多效蒸发器-工业废水蒸发器厂家-康景辉集团官网 | 冲锋衣滑雪服厂家-冲锋衣定制工厂-滑雪服加工厂-广东睿牛户外(S-GERT) | 粉末包装机,拆包机厂家,价格-上海强牛包装机械设备有限公司 | 台湾阳明固态继电器-奥托尼克斯光电传感器-接近开关-温控器-光纤传感器-编码器一级代理商江苏用之宜电气 | 浙江富广阀门有限公司| 武汉EPS线条_EPS装饰线条_EPS构件_湖北博欧EPS线条厂家 | 台湾阳明固态继电器-奥托尼克斯光电传感器-接近开关-温控器-光纤传感器-编码器一级代理商江苏用之宜电气 | 乐考网-银行从业_基金从业资格考试_初级/中级会计报名时间_中级经济师 | 真空干燥烘箱_鼓风干燥箱 _高低温恒温恒湿试验箱_光照二氧化碳恒温培养箱-上海航佩仪器 | 培训中心-翰香原香酥板栗饼加盟店总部-正宗板栗酥饼技术 | 北京网站建设-企业网站建设-建站公司-做网站-北京良言多米网络公司 | 组织研磨机-高通量组织研磨仪-实验室多样品组织研磨机-东方天净 传递窗_超净|洁净工作台_高效过滤器-传递窗厂家广州梓净公司 | 数码管_LED贴片灯_LED数码管厂家-无锡市冠卓电子科技有限公司 | 扒渣机厂家_扒渣机价格_矿用扒渣机_铣挖机_撬毛台车_襄阳永力通扒渣机公司 | 深圳APP开发_手机软件APP定制外包_小程序开发公司-来科信 | 南汇8424西瓜_南汇玉菇甜瓜-南汇水蜜桃价格 | 陕西安闸机-伸缩门-车牌识别-广告道闸——捷申达门业科技 |