它的领域中同其它模式的不同之处在于它并没有明确要求我们使用一个构造器。取而代之,一个工厂能提供一个创建对象的公共接口,我们可以在其中指定我们希望被创建的工厂对象的类型。

  • 简单工厂模式:使用一个类(通常为单体)来生成实例
  • 复杂工厂模式:使用子类来决定一个变量成员应该为哪个具体的类的实例.

简单工厂模式

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设计模式——工厂模式详解的更多相关文章

  1. JAVA 设计模式之 工厂模式详解

    一.简单工厂模式 简单工厂模式(Simple Factory Pattern)是指由一个工厂对象决定创建出哪一种产品类 的实例.属于创建型模式,但它不属于 GOF,23 种设计模式 (参考资料: ht ...

  2. Java设计模式(5:设计模式的分类及工厂模式详解)

    一.设计模式的分类 总的来说,设计模式可以分为三大类:创建型模式.结构型模式.行为型模式,具体如下图: 二.工厂模式 工厂模式分为简单工厂模式.工厂方法模式和抽象工厂模式.其中简单工厂模式并不属于23 ...

  3. 抽象工厂模式详解 —— head first 设计模式

    项目实例 假设你有一家 pizza 店,你有很多种 pizza,要在系统中显示你所有 pizza 种类.实现这个功能并不难,使用普通方式实现: public class PizzaStore { Pi ...

  4. js设计模式-工厂模式(抽象工厂)

    场景:定义一个抽象类 AbsProducer(生产商),该生产商有两个行为,一个生产,一个出售,其中生产方法为抽象方法,由具体的厂家(工厂)去实现,出售的产品均是电子产品(返回的对象为电子产品对象,即 ...

  5. js设计模式--工厂模式

    工厂模式: 工厂模式的目的是为了创建对象,它经常是在类和类的方法中实现.简单的工厂模式是由一个方法来决定到底要创建哪类的实例,这些实例经常拥有相同的接口,这种模式在所实例化的类型在编译期并不确定,而是 ...

  6. js的严格模式详解

    什么是js的严格模式? 严格模式指的是使js在更为严格的条件下运行.严格模式的主要作用是规范我们写代码习惯,以及为js升级做好铺垫.  如何使用严格模式? <script> //直接在代码 ...

  7. [js]js设计模式-工厂模式

    // 定义一个人 var p1 = { name: 'wxb', age: 22, writejs: function () { console.log(this.name + ' can sing. ...

  8. java之简单工厂模式详解

    设计模式(Design pattern)是一套被反复使用.多数人知晓的.经过分类编目的.代码设计经验的总结.使用设计模式是为了可重用代码.让代码更容易被他人理解.保证代码可靠性. 毫无疑问,设计模式于 ...

  9. Java设计模式-策略模式详解

    前言 在软件领域中,设计模式作为一种经典的开发实践常常需要我们去深入的理解,而策略模式作为设计模式的一种,使用频率也是相对来说比较高的,在Java中,当我们学习TreeSet集合的时候,就采用了经典的 ...

随机推荐

  1. hdu 6034 B - Balala Power! 贪心

    B - Balala Power! 题目链接 http://acm.hdu.edu.cn/showproblem.php?pid=6034 题面描述 Talented Mr.Tang has n st ...

  2. vscode eslint配置vue遇到的问题

    一.准备工作 vscode里安装eslint和vetur插件,全局安装eslint,并在项目根目录中eslint --init 二.Cannot find module 'eslint-config- ...

  3. python之装饰器篇

    一.基本装饰器 基本装饰器的作用: 在不改变原函数的基础上, 通过装饰器, 给原函数新增某些功能 实现方法: 在原函数上加 @装饰器名字 其中@叫做语法糖 定义装饰器 第一层函数传入参数(用于传入原函 ...

  4. JS_高程3.基本概念(6)函数

    1.ECMAScript中的函数使用function关键字来声明. eg: function sum (num1,num2){ alert(num1+num2); } sum(3,7); 注意: 在有 ...

  5. 通过TopShelf快速开发服务程序

    我之前在文章中介绍过使用NSSM将exe封装为服务,这种方式我个人是比较喜欢的,一来原始文件不受服务的开发约束,二来也可以提供简单的日志系统.线程守护等功能,是我个人比较倾向的行为.但是,有的场景下, ...

  6. txt2xls

    #!/bin/env python# -*- encoding: utf-8 -*-import datetimeimport timeimport osimport sysimport openpy ...

  7. Unity2017灯光烘焙知识点

    去研究一下灯光探针,性能可以提升不少.

  8. netty源码解析目录

    第一章 java nio三大组件与使用姿势 二.netty使用姿势 三.netty服务端启动源码 四.netty客户端启动源码 五.NioEventLoop与netty线程模型 六.ChannelPi ...

  9. C++ delegate的几种方法

    https://stackoverflow.com/questions/9568150/what-is-a-c-delegate You have an incredible number of ch ...

  10. Data type conversion in MongoDB

    [问题] I have a collection called Document in MongoDB. Documents in this collection have a field calle ...