工厂模式创建对象(视为工厂里的产品)时无需指定创建对象的具体类。
工厂模式定义一个用于创建对象的接口,这个接口由子类决定实例化哪一个类。该模式使一个类的实例化延迟到了子类。而子类可以重写接口方法以便创建的时候指定自己的对象类型。
在这里将工厂简单分为三种:
//基类有共同的提出来functionbasePet(){this.register=function(){document.write("宠物登记...
");}this.eat=function(){document.write("宠物吃饭...
");}}(4)各个实现类---这里是各种动物
functionDog(){Dog.superClass.constructor.call(this);//继承父类//实现接口部分this.run=function(){document.write("小狗跑......
")}this.sing=function(){document.write("小狗唱歌......
")}}functionCat(){Cat.superClass.constructor.call(this);//继承父类//实现接口部分this.run=function(){document.write("小猫跑......
")}this.sing=function(){document.write("小猫唱歌......
")}}functionPig(){Pig.superClass.constructor.call(this);//继承父类//实现接口部分this.run=function(){document.write("小猪跑......
")}this.sing=function(){document.write("小猪唱歌......
")}}functionBird(){Bird.superClass.constructor.call(this);//继承父类//实现接口部分this.run=function(){document.write("小鸟跑......
")}this.sing=function(){document.write("小鸟唱歌......
")}}(5)各个实现类继承基类
//继承extend(Dog,basePet);extend(Cat,basePet);extend(Pig,basePet);extend(Bird,basePet);(6)创建宠物的开始卖宠物
varnewPetShop=newPetShop();varflowerPig=newPetShop.sellPet("pig");flowerPig.run();结果为:
总结一下,上述好像没怎么体现有关工厂之类的,我们应该注意到这么一个问题就是:当需要增加一个新品种宠物时,我们需要修改'宠物店类',耦合度较高。
为了解决这个问题我们使用简单工厂模式来解决。
2,简单工厂模式(针对上述的改进)
(1)接口文件与继承文件的的引入同上面
(2)静态工厂
//使用工厂方式创建宠物对象//静态工厂varfactoryPet={//出售宠物的方法getPet:function(kind){//宠物对象varpet;//宠物种类switch(kind){case'dog':pet=newDog();break;case'cat':pet=newCat();break;case'pig':pet=newPig();break;default:pet=newBird();}//验证接口Interface.ensureImplement(pet,Pet);//判断pet对象是否全部实行接口Pet里面全部的方法returnpet;}}(3)利用工厂创建宠物店对象
varfactoryPetShop=function(){}factoryPetShop.prototype={getPet:function(kind){varpet=factoryPet.getPet(kind);pet.eat();pet.register();returnpet;}}(4)从宠物店购买宠物实现
varnewPetShop=newfactoryPetShop();varflowerCat=newPetShop.getPet("cat");flowerCat.sing();(5)使用简单工厂实现的全部代码(数字标号表示其思考的先后顺序)
所以我们需要根据各个厂家的需求,有不同的工厂,各个卖家可以根据自己需求使用不同的工厂(其实是利用不同子类实现各自合适的工厂),用于满足每个宠物店的不同。
于是我们有了复杂的工厂用来解决该问题。
3,复杂工厂:通过把实例化的任务交给子类来完成的,用以到达松耦合的目的。
此处同样是根据上述进行改进的,还是简单的说明一下实现过程
(1)在html中将接口文件的引进,代码为
/*创建extend函数为了程序中所有的继承操作*///subClass:子类superClass:超类functionextend(subClass,superClass){//1,使子类原型属性等于父类的原型属性//初始化一个中间空对象,目的是为了转换主父关系varF=function(){};F.prototype=superClass.prototype;//2,让子类继承FsubClass.prototype=newF();subClass.prototype.constructor=subClass;//3,为子类增加属性superClass==》原型链的引用subClass.superClass=superClass.prototype;//4,增加一个保险,就算你的原型类是超类(Object)那么也要把你的构造函数级别降下来if(superClass.prototype.constructor==Object.prototype.constructor){superClass.prototype.constructor=superClass;}}(3)分析各个类提出相同的部分作为基类,基类代码如下
//基类分析后有共同的提出来作为基类functionbasePet(){this.register=function(){document.write("宠物登记。。。。
");};this.eat=function(){document.write("宠物吃饭。。。。
");}}(4)各个具体的实现类:继承基类+接口实现
//各个宠物类(实现类)继承基类+接口实现functionDog(){Dog.superClass.constructor.call(this);//继承父类//实现接口this.run=function(){document.write("小狗跑......
")}this.sing=function(){document.write("小狗唱歌......
")}}functionCat(){Cat.superClass.constructor.call(this);//继承父类//实现接口this.run=function(){document.write("小猫跑......
")}this.sing=function(){document.write("小猫唱歌......
")}}functionPig(){Pig.superClass.constructor.call(this);//继承父类//实现接口this.run=function(){document.write("小猪跑......
")}this.sing=function(){document.write("小猪唱歌......
")}}functionBird(){Bird.superClass.constructor.call(this);//继承父类//实现接口this.run=function(){document.write("小鸟跑......
")};this.sing=function(){document.write("小鸟唱歌......
")}}(5)实现类与基类的继承实现,代码如下(调用extend())
extend(Dog,basePet);//动物狗继承基类extend(Cat,basePet);extend(Pig,basePet);extend(Bird,basePet);(6)将商店抽取出来,做成抽象类,代码如下
//把核心商店抽取出来varpetShop=function(){};petShop.prototype={//模拟抽象类需要被子类覆盖getPet:function(kind){varpet=this.getpet(kind);pet.eat();pet.register();returnpet;},getpet:function(model){thrownewError("该类是抽象类,不能实例化")}};(7)利用子类来满足各个商家的不同类型宠物店的实现,代码如下
//利用子类来满足之前的需求(多态)varoneShop=function(){}extend(oneShop,petShop);//继承//覆写方法oneShop.prototype.getpet=function(model){//宠物对象varpet;//宠物种类switch(model){case'dog':pet=newDog();break;default:pet=newBird();}//验证接口Interface.ensureImplement(pet,Pet);//判断pet对象是否全部实行接口Pet里面全部的方法pet.eat();pet.register();returnpet;};同上,这个也是一个不同的子类
twoShop=function(){};extend(twoShop,petShop);//商店的继承//覆写方法twoShop.prototype.getPet=function(model){//宠物对象varpet;//宠物种类switch(kind){case'pig':pet=newPig();break;default:pet=newBird();}//验证接口Interface.ensureImplement(pet,Pet);//判断pet对象是否全部实行接口Pet里面全部的方法pet.eat();pet.register();returnpet;};(8)使用,实质是子类对父类的实例化
这里实现其中一个宠物店,另外一个同理。
//子类对父类的实例化varjim=newoneShop();varpig=jim.getpet("dog");pig.run();pig.sing()(9)上述代码综合在一起为,代码如下
总结一下,在该个模式中主要体现在多态多一点。现在我们将前面的各种综合在一起使用JavaScript的eval()做一个智能化的工厂。
4,通过eval()实现智能化工厂
(1)接口文件和继承文件的引入,如上述的一模一样,这里将不再重复贴代码了,直接开始我们的新东西吧。
(2)接口调用
varPet=newInterface("Pet",["eat","run","sing","register"]);(3)将相同部分提取出来(简单的提取)
//基类分析后有共同的提出来作为基类functionbasePet(){this.register=function(){document.write("宠物登记。。。。
");};this.eat=function(){document.write("宠物吃饭。。。。
");}}(4)各动物类
//实现类继承基类+接口实现functionDog(){Dog.superClass.constructor.call(this);//继承父类//实现接口this.run=function(){document.write("小狗跑......
")}this.sing=function(){document.write("小狗唱歌......
")}}functionCat(){Cat.superClass.constructor.call(this);//继承父类//实现接口this.run=function(){document.write("小猫跑......
")}this.sing=function(){document.write("小猫唱歌......
")}}functionPig(){Pig.superClass.constructor.call(this);//继承父类//实现接口this.run=function(){document.write("小猪跑......
")}this.sing=function(){document.write("小猪唱歌......
")}}functionBird(){Bird.superClass.constructor.call(this);//继承父类//实现接口this.run=function(){document.write("小鸟跑......
")};this.sing=function(){document.write("小鸟唱歌......
")}}(5)实现各动物类继承基类
//继承extend(Dog,basePet);extend(Cat,basePet);extend(Pig,basePet);extend(Bird,basePet);(6)将商店核心抽取出来,做成一个抽象类,代码如下,
varpetShop=function(){};petShop.prototype={//模拟抽象类需要被子类覆盖getPet:function(kind){varpet=this.getpet(kind);pet.eat();pet.register();returnpet;},getpet:function(model){thrownewError("该类是抽象类,不能实例化")}};//这里是做成抽象类其中的getpet方法是通过子类实现的。
(7)做一个智能工厂
//(5)智能工厂只负责生成宠物varPetFactory={sellPet:function(kind){varpet;pet=eval("new"+kind+"()");Interface.ensureImplement(pet,Pet);//判断pet对象是否全部实行接口Pet里面全部的方法returnpet;}}(8)利用子类来满足各个商家的不同类型宠物店的实现,代码如下
其中一个子类
//利用子类来满足各个商家的不同类型宠物店的实现(多态)varoneShop=function(){};extend(oneShop,petShop);//继承//覆写方法oneShop.prototype.getpet=function(model){//宠物对象varpet=null;//宠物种类varpets=["Dog","Cat","Bird"];//商店自己拥有的宠物宠物货架for(vinpets){//循环出索引if(pets[v]==model){//model是我们自己传递过来需要创建的宠物pet=PetFactory.sellPet(model);//验证接口Interface.ensureImplement(pet,Pet);//判断pet对象是否全部实行接口Pet里面全部的方法pet.eat();pet.register();break;}}returnpet;另一个子类
//(商店2)利用子类来满足各个商家的不同类型宠物店的实现(多态)twoShop=function(){};extend(twoShop,petShop);//商店的继承//覆写方法twoShop.prototype.getPet=function(model){//宠物对象varpet=null;//宠物种类varpets=["Pig"];//商店自己拥有的宠物for(vinpets){//循环出索引if(pets[v]==model){pet=PetFactory.sellPet(model);//验证接口Interface.ensureImplement(pet,Pet);//判断pet对象是否全部实行接口Pet里面全部的方法pet.eat();pet.register();break;}}returnpet;};(9)实现开宠物店卖宠物
这里我们来开第二个商店,卖Pig
varshop=newtwoShop();//创建商店varpet=shop.getPet("Pig");//从商店中得到宠物pet.run();//宠物的功能