工厂方法模式
前言
今天自己看了一下自己写的部分博客,发现写的好丑....开始注意自己的排版!!但是偏亮也不是一朝一夕就完成的,我尽量让它漂亮一点.....每天漂亮一点点
正文
工厂方法模式是一种实现”工厂”概念的面向对象设计模式.实质是定义一个创建对象的接口,但是让实现这个接口的类来决定实例化哪个类.工厂方法让类的实例化推迟到子类中进行.
创建一个对象常常需要复杂的过程,所以不适合在一个复杂的对象中.创建对象可能会导致大量的重复代码,也可能提供不了足够级别的抽象.工厂方法模式通过定义一个单独的创建对象的方法来解决这些问题,由子类实现这个方法来创建具体类型的对象.
//几个Button类 class Button{/* ...*/} class WinButton extends Button{/* ...*/} class MacButton extends Button{/* ...*/} //它们的工厂类 interface ButtonFactory{ abstract Button createButton(); } class WinButtonFactory implements ButtonFactory{ Button createButton(){ return new WinButton(); } } class MacButtonFactory implements ButtonFactory{ Button createButton(){ return new MacButton(); } }
在JS中创建对象会习惯的使用new关键字和类构造函数(淡然主要还是对象字面量),问题在于这样会导致两个类之间产生依赖性.
工厂模式就是一种又处于消除两个类依赖性的模式.
简单工厂模式:使用一个类(通常为单体)来生成实例
复杂工厂类:使用子类来决定一个变量成员应该为哪个具体的类的实例.
实例1:简单工厂模式
对于自行车商店出售自行车
var BicycleShop=function(){}; BicycleShop.prototype={ sellBicycle:function (model){ var bicycle; switch(model){ case "A"://A类型的自行车 bicycle=new A(); break; case "B": bicycle=new B(); break; case "C": bicycle=new C(); break; } Interface.ensureImplements(bicycle,Bicycle); return bicycle; } }
分析:
sellBicycle方法根据所提示的的自行车型号来进行自行车的实例创建.各种型号的自行车实例可以互换使用,因为他们都实现了Bicycle接口.
注意:接口在工厂模式中起着很重要的作用.如果部队对象进行某种类型检查以确保其实现了必需的方法,工厂模式带来的好处也就所剩无几了.
那么对于ABC这家店铺来说,我需要它的A车型,那么我只需要
var ABC=new BicycleShop(); var myBike=ABC.sellBicycle(“A”);
以上方式很管用,但是一但说我需要添加一些自行车款式的时候,比如我想能生产D类型的自行车,这就需要我修改BicycleShop的switch部分,那么只要是修改就有可能带来BUG.所以,将这部分生成实例的代码提出来交给一个简单的工厂对象是一个很不错的方法.
var BicycleFactory={ createBicycle:function(model){ var bicycle; switch(model){ case "A": bicycle=new A(); break; case "B": bicycle=new B(); break; case "C": default: bicycle=new C(); break; } return bicycle; } }
BicycleFactory是一个脱离于BicycleShop的单体.用来把createBicycle方法封装在一个命名空间中.BicycleFactory返回一个实现了Bicycle接口的对象.当需要添加新的类型的时候,不需要懂BicycleShop只需要修改工厂单体对象就可以:
var BicycleShop=function (){}; BicycleShop.prototype={ sellBicycle:function(model){ var bicycle=BicycleFactory.createBicycle(model); return bicycle; } }
以上就是一个很好的简单工厂的实例.该模式将成员对象的创建工作交给一个外部对象实现,该外部对象可以是一个简单的命名空间,也可以是一个类的实例.
实例2:工厂模式
真正的工厂模式与简单工厂模式对比,主要区别就是它不是另外使用一个对象或者类来创建实例(自行车),而是使用一个子类.工厂是一个将其成员对象的实例化推迟到子类中进行的类.
比如BicycleShop可以决定从那一家厂商进行进货,那么简单的一个BicycleFactory是不够的,因为各个厂商会各自生产不同型号的自行车,所以首先需要生成各自厂商的shop实例,不同厂商的shop实例拥有不同的生成几个型号自行车的方法.
也就是相当于将自行车对象的实例化推迟到了shop实例中产生.
基础:
</pre><p><pre name="code" class="javascript">var BicycleShop=function (){}; BicycleShop.prototype={ sellBicycle:function(model){ var bicycle=BicycleFactory.createBicycle(model); return bicycle; }, createBicycle:function(model){ throw new Error("在使用类不支持的操作"); } }
这个类定义了createBicycle方法,但真要调用这个方法的话,会抛出一个错误.现在BicycleShop是一个抽象类,他不能被实例化,只能用来派生子类.设计一个经销特定自行车生产厂家产品的子类需要扩展BicycleShop,重定义其中的createBicycle方法.
各自厂商:
var ABicycleShop=function(){}; extend(ABicycleShop,BicycleShop); ABicycleShop.prototype.createBicycle=function(model){ var dicycle; switch(model){ case "A": bicycle=new A(); break; case "B": bicycle=new B(); break; case "C": default: bicycle=new C(); break; } return bicycle; } var BBicycleShop=function(){}; extend(BBicycleShop,BicycleShop); BBicycleShop.prototype.createBicycle=function(model){ var dicycle; switch(model){ case "A": bicycle=new A(); break; case "B": bicycle=new B(); break; case "C": default: bicycle=new C(); break; } return bicycle; }
那么接下来就很简单了,对于来自A厂商的货
var aShop=new ABicycleShop();
var newBicycle=aShop.sellBicycle(“A”);
当然,你也可以对于外层生成的子类实例在使用简单工厂模式进行包装一下,对于添加其他厂商也很简单,再创建一个Bicycle的子类重定义其createBicycle的工厂方法即可.
工厂模式使用场合
1.动态实现
例如自行车的例子,创建一些用不同方式实现统一接口的对象,那么可以使用一个工厂方法或者简单工厂对象来简化实现过程.选择可以是明确进行的也可以是隐含的.
2.节省开销
如果对象要进行复杂的并且批次相关的设置的时候,那么工厂模式可以显著的减少每种队形的代码量.将特定的设置代码提取出来会使得代码有极大的提升.并且能优化结构便于维护.
3.用于许多小型对象组成一个大对象
4使用工厂模式的优缺点
好处是可以消除对象见的耦合,通过使用工程方法而不是new 关键字.将所有实例化的代码集中在一个位置房子代码重复.
缺点是大多数类最好使用new关键字和构造函数,可以让代码更加简单易读.而不必去查看工厂方法来知道.
版权声明:本文为博主原创文章,未经博主允许不得转载。