它的领域中同其它模式的不同之处在于它并没有明确要求我们使用一个构造器。取而代之,一个工厂能提供一个创建对象的公共接口,我们可以在其中指定我们希望被创建的工厂对象的类型。
- 简单工厂模式:使用一个类(通常为单体)来生成实例
- 复杂工厂模式:使用子类来决定一个变量成员应该为哪个具体的类的实例.
简单工厂模式
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;
}
return bicycle;
}
}
以上方式很管用,但是如果需要添加一些自行车款式的时候,比如我想能生产D类型的自行车,这就需要修改BicycleShop的switch部分,这样就不太好了。
复杂工厂模式
为了和简单工厂形成对比,这里还是采用BicycleShop为例来说明工厂模式的设计理念。
我们打算让各个自行车商店自行决定从哪个生产厂家进货。鉴于此,单靠一个自行车工厂(BicycleFactory)是无法提供需要的所有的自行车的。 所以我们考虑将BicycleShop设计为一个抽象类,让子类根据各自的进货渠道实现其进货自行车(createBicycle)的工作:
var BicycleShop = function(){};
BicycleShop.prototype = {
sellBicycle : function(model){
//让其子类来完成这个工作
var bicycle = this.createBicycle(model);
return bicycle;
},
//抽象方法,必须实现后才能调用
createBicycle : function(model){
throw new Error("必须通过子类的实例才能调用此方法,进货自行车");
}
};
BicycleShop类中定义了一个createBicycle方法,该方法一旦调用就会抛出异常,因此,该类是不能直接实例化的,该抽象类必须被继承,通过其子类来完成createBicycle的工作。
工厂模式实现
下面定义了两个子类,一个子类代表从Oracle公司进货的商店,一个子类代表从IBM公司进货的商店,代码如下:
//Oracle自行车商店
var OracleBicycleShop = function(){};
//继承父类
inherits(OracleBicycleShop,BicycleShop);
//实现createBicycle方法
OracleBicycleShop.prototype.createBicycle = function(model){
var bicycle;
//生产自行车
switch(model){
case "speedster":
bicycle = new OracleSpeedster();
break;
case "lowrider":
bicycle = new OracleLowrider();
break;
case "Alien":
bicycle = new OracleAlien();
break;
case "comfort cruiser":
default :
bicycle = new OracleComfortCruiser();
}
return bicycle;
}; //IBM自行车商店
var IBMBicycleShop = function(){};
//继承父类
inherits(IBMBicycleShop,BicycleShop);
//实现createBicycle方法
IBMBicycleShop.prototype.createBicycle = function(model){
var bicycle;
//生产自行车
switch(model){
case "speedster":
bicycle = new IBMSpeedster();
break;
case "lowrider":
bicycle = new IBMLowrider();
break;
case "Alien":
bicycle = new IBMleAlien();
break;
case "comfort cruiser":
default :
bicycle = new IBMComfortCruiser();
}
return bicycle;
};
经过这样的一个设计,就产生了专卖店的概念,OracleBicycleShop表示Oracle自行车专卖店,IBMBicycleShop则表示IBM自行车专卖店。现在,如果用户需要购买Speedster牌的自行车,无论跑到那个专卖店,都可以买到了,示例代码如下:
//到Oracle专卖店购买
var oracle = new OracleBicycleShop();
var yourNewBicycle = oracle.createBicycle("speedster"); //到IBM专卖店购买
var ibm = new IBMBicycleShop();
var myNewBicycle = ibm.createBicycle("speedster");
即便是要增加对其他生产厂家的支持,也是很简单的,只需要再创建一个BicycleShop的子类并实现其createBicycle方法即可。
根据不同的需求,对各个子类进行修改,以支持更多厂家其他型号的产品,这是工程设计模式最重要的特点。
JS设计模式——工厂模式详解的更多相关文章
-
JAVA 设计模式之 工厂模式详解
一.简单工厂模式 简单工厂模式(Simple Factory Pattern)是指由一个工厂对象决定创建出哪一种产品类 的实例.属于创建型模式,但它不属于 GOF,23 种设计模式 (参考资料: ht ...
-
Java设计模式(5:设计模式的分类及工厂模式详解)
一.设计模式的分类 总的来说,设计模式可以分为三大类:创建型模式.结构型模式.行为型模式,具体如下图: 二.工厂模式 工厂模式分为简单工厂模式.工厂方法模式和抽象工厂模式.其中简单工厂模式并不属于23 ...
-
抽象工厂模式详解 —— head first 设计模式
项目实例 假设你有一家 pizza 店,你有很多种 pizza,要在系统中显示你所有 pizza 种类.实现这个功能并不难,使用普通方式实现: public class PizzaStore { Pi ...
-
js设计模式-工厂模式(抽象工厂)
场景:定义一个抽象类 AbsProducer(生产商),该生产商有两个行为,一个生产,一个出售,其中生产方法为抽象方法,由具体的厂家(工厂)去实现,出售的产品均是电子产品(返回的对象为电子产品对象,即 ...
-
js设计模式--工厂模式
工厂模式: 工厂模式的目的是为了创建对象,它经常是在类和类的方法中实现.简单的工厂模式是由一个方法来决定到底要创建哪类的实例,这些实例经常拥有相同的接口,这种模式在所实例化的类型在编译期并不确定,而是 ...
-
js的严格模式详解
什么是js的严格模式? 严格模式指的是使js在更为严格的条件下运行.严格模式的主要作用是规范我们写代码习惯,以及为js升级做好铺垫. 如何使用严格模式? <script> //直接在代码 ...
-
[js]js设计模式-工厂模式
// 定义一个人 var p1 = { name: 'wxb', age: 22, writejs: function () { console.log(this.name + ' can sing. ...
-
java之简单工厂模式详解
设计模式(Design pattern)是一套被反复使用.多数人知晓的.经过分类编目的.代码设计经验的总结.使用设计模式是为了可重用代码.让代码更容易被他人理解.保证代码可靠性. 毫无疑问,设计模式于 ...
-
Java设计模式-策略模式详解
前言 在软件领域中,设计模式作为一种经典的开发实践常常需要我们去深入的理解,而策略模式作为设计模式的一种,使用频率也是相对来说比较高的,在Java中,当我们学习TreeSet集合的时候,就采用了经典的 ...
随机推荐
-
设计模式之六大原则——接口隔离原则(ISP)
设计模式之六大原则——接口隔离原则(ISP) 转载于:http://www.cnblogs.com/muzongyan/archive/2010/08/04/1792528.html 接口隔离原则 ...
-
单例模式-C++
单例模式(Singleton) --本文内容部分引自<大话设计模式 Chapter21> 一.概念:保证一个类仅有一个实例,并提供一个访问它的全局访问点. 通常我们可以让一个全局变量使一个 ...
-
JavaScript常用技巧总结(持续添加中...)
在我学习过程中收集的一些常用技巧: typeof x !== undifined 判断x是否已定义: x === Object(x) 判断x是否为对象: Object.keys(x).length ...
-
使用Grub Rescue恢复Ubuntu引导
装了Ubuntu和Window双系统的电脑,通常会使用Ubuntu的Grub2进行引导. Grub2会在MBR写入引导记录,并将引导文件放在/boot/grub,破坏任意一项都会导致系统无法正常启动. ...
-
uva 1151(最小生成树,枚举子集)
题意:平面上有n个点(1<=N<=1000),你的任务是让所有n个点连通,为此,你可以新建一些边,费用等于两个端点的欧几里得距离的平方.另外还有q(0<=q<=8)个套餐,可以 ...
-
iOS:FFmpeg视频播放和直播框架
视频直播和播放转码器框架 介绍: FFmpeg是一套可以用来记录.转换数字音频.视频,并能将其转化为流的开源计算机程序.采用LGPL或GPL许可证. 它提供了录制.转换以及流化音视频的完整解决方案.它 ...
-
MVC4.0 WebApi如何自定义返回数据类型
1.客户端可以通过HTTP Accept消息头来通知服务器客户端想要什么样的MIME类型数据,例如:application/json则代表告诉服务器想要的是Json数据 2.服务器端撇开客户端的请求类 ...
-
Microsoft.SharePoint.Security的问题
请求“Microsoft.SharePoint.Security.SharePointPermission, Microsoft.SharePoint.Security, Version=12.0.0 ...
-
(转)java 多线程 CountDownLatch用法
CountDownLatch,一个同步辅助类,在完成一组正在其他线程中执行的操作之前,它允许一个或多个线程一直等待. 主要方法 public CountDownLatch(int count); pu ...
-
CentOS7 配置Mailx使用SMTP发送邮件
mail.mailx和sendmail介绍: mail是mailx的别名,最初叫nail(与arch linux目前用的S-nail基因相同):mail是Heirloom的一个子项目.sendmail ...