Javascript设计模式理论与实战:工厂方法模式
本文从简单工厂模式的缺点说起,引入工厂方法模式,介绍的工厂方法模式的基本知识,实现要点和应用场景,最后举例进行说明工厂方法模式的应用。
在之前的《Javascript设计模式理论与实战:简单工厂模式》这篇文章中,我们介绍了简单工厂的知识和一些应用。简单工厂模式存在一个唯一的工厂类,它的优点是所有产品类的实例化集中管理,便于理解,但这既是优点也是缺点。如果
产品类的数量较少并且不会经常发生变化,我们可以直接利用简单工厂模式,但是有的时候,需求是随时在变的,产品类也可能随时在增加,如果使用简单工厂模式,就不可避免的要去修改工厂类的代码。要解决这个问题,就要提到今天要说的工厂方法模式。
基本概念
工厂方法模式:不再有一个唯一的工厂类就创建产品,而是将不同的产品交给对应的工厂子类去实现。每个产品由负责生产的子工厂来创造。如果添加新的产品,需要做的是添加新的子工厂和产品,而不需要修改其他的工厂代码。
工厂方法模式主要有三种类组成:
1.抽象工厂类:负责定义创建产品的公共接口。
2.产品子工厂:继承抽象工厂类,实现抽象工厂类提供的接口
3.每一种产品各自的产品类
工厂方法模式的实现
首先,我们对《Javascript设计模式理论与实战:简单工厂模式》一文中简单工厂模式的代码进行改造。下面是简单工厂公式的代码:
var productEnums = {
flight: "flight",
hotel: "hotel"
};
function Flight() {
console.log("This is Flight");
}
function Hotel() {
console.log("This is Hotel");
}
var productFactory = (function () {
var productFactories = {
"flight": function () {
return new Flight();
},
"hotel": function () {
return new Hotel();
}
}; return {
createProduct: function (productType) {
return productFactories[productType]();
}
}
})();
function User() {
this.shopCart = [];
}
User.prototype = {
constructor: User,
order: function (productType) {
this.shopCart.push(productFactory.createProduct(productType));
}
}
要将上面的代码修改成工厂方法模式,首先要构造一个抽象工厂类。在JS中,由于我们抽象类的概念,我们无法做到像Java,C#的抽象工厂类,但是我们可以去模拟它。代码如下
function AbstractFactory() {
}
AbstractFactory.prototype.createProduct = function () {
throw "没有实现该方法";
}
在这段代码中,定义了一个工厂类,然后定义了它的一个方法CreateProduct,这个方法模拟抽象方法,不提供具体实现,而是抛出错误,继承的工厂类就要去实现具体方法,否则会抛错,这就模拟了一个抽象工厂类。
定义完抽象工厂类后,现在我们要做的就是定义子工厂去实现它,我们分别定义两个子工厂FlightFactory和HotelFactory。
function FlightFactory() {
AbstractFactory.call(this);
}
FlightFactory.prototype = new AbstractFactory();
FlightFactory.prototype.createProduct = function () {
return new Flight();
}
function HotelFactory() {
AbstractFactory.call(this);
}
HotelFactory.prototype = new AbstractFactory();
HotelFactory.prototype.createProduct = function () {
return new Hotel();
}
以上代码分别定义了两个子工厂类,每个子类继承抽象工厂类,然后实现createProduct方法,每一种产品在各自的工厂类里创建。
在客户端怎么调用呢?
var factory = new FlightFactory();
factory.createProduct();
factory = new HotelFactory();
factory.createProduct();
疑点解答
首先我们要理解一个概念:开放封闭原则。
软件实体应该是可扩展但不可修改的,就是对扩展是开放但是对修改是封闭的。体现在两个方面:
(1)对扩展开放,产品有新需求或变活时,可以对现有代码进行扩展,以适应新变化
(2)对修改封闭,类一旦设计完成,就不应该对其进行修改。
下面来说说几个疑点
1、相比于简单工厂模式,工厂方法模式增多了一个抽象工厂类和多个子工厂类,这样代码不是更复杂了吗?
确实,代码比简单工厂模式复杂了,引入了抽象层,还有子工厂,这会增加代码的复杂度和理解难度。但是相比于简单工厂模式,代码的维护性和扩展性提高了,新增产品时,只需要增加对应的产品类和产品工厂类,不需要修改到抽象工厂类和其他子工厂。更加符合面向对象的开放封闭原则。
当然具体场景具体分析,复杂性和扩展性相比如何舍去,在使用的时候要结合实际场景去分析。
2、在客户端调用的时候,每一种产品还是需要知道具体的工厂类来调用,好像区别不大?
和简单工厂模式的区别在于:我们将判断使用哪一个产品类的代码从工厂类转移到了调用的客户端这里,如果有新功能要添加,我们要修改的是客户端的代码而不是工厂类的代码,这样才符合开放封闭原则。
总结
实现要点
在JS中,我们实现工厂方法模式主要包括3个角色:
1.抽象工厂类:提供工厂方法的声明
2.子工厂类:实现抽象工厂类的工厂方法
3.产品类:具体的产品类
优缺点
优点:克服了简单工厂模式的缺点。如果需要增加新的产品类,无须修改现有系统,只需要增加新的工厂类和产品类;每个工厂类封装了产品对象的创建细节,系统具有良好的灵活性和可扩展性。
缺点:增加新产品的同时需要增加新的工厂,导致系统类的个数成对增加,在一定程度上增加了系统的复杂性。
原文地址:http://luopq.com/2015/11/10/design-pattern-factory-method/
Javascript设计模式理论与实战:工厂方法模式的更多相关文章
- Javascript设计模式理论与实战:桥接模式
桥接模式将抽象部分与实现部分分离开来,使两者都可以独立的变化,并且可以一起和谐地工作.抽象部分和实现部分都可以独立的变化而不会互相影响,降低了代码的耦合性,提高了代码的扩展性. 基本理论 桥接模式定义 ...
- Javascript设计模式理论与实战:状态模式
在软件开发中,很大部分时候就是操作数据,而不同数据下展示的结果我们将其抽象出来称为状态,我们平时开发时本质上就是对应用程序的各种状态进行切换并作出相应处理.状态模式就是一种适合多种状态场景下的设计模式 ...
- Javascript设计模式理论与实战:组合模式
我们平时开发过程中,一定会遇到这种情况:同时处理简单对象和由简单对象组成的复杂对象,这些简单对象和复杂对象会组合成树形结构,在客户端对其处理的时候要保持一致性.比如电商网站中的产品订单,每一张产品订单 ...
- 前端读者 | Javascript设计模式理论与实战:状态模式
本文来自 @狼狼的蓝胖子:链接:http://luopq.com/2015/11/25/design-pattern-state/ 在软件开发中,很大部分时候就是操作数据,而不同数据下展示的结果我们将 ...
- Java设计模式(二) 工厂方法模式
本文介绍了工厂方法模式的概念,优缺点,实现方式,UML类图,并介绍了工厂方法(未)遵循的OOP原则 原创文章.同步自作者个人博客 http://www.jasongj.com/design_patte ...
- 重学 Java 设计模式:实战工厂方法模式
作者:小傅哥 博客:https://bugstack.cn 沉淀.分享.成长,让自己和他人都能有所收获!
- Java设计模式学习笔记(三) 工厂方法模式
前言 本篇是设计模式学习笔记的其中一篇文章,如对其他模式有兴趣,可从该地址查找设计模式学习笔记汇总地址 1. 简介 上一篇博客介绍了简单工厂模式,简单工厂模式存在一个很严重的问题: 就是当系统需要引入 ...
- 设计模式(三)工厂方法模式(Factory Pattern)
一.引言 在简单工厂模式中讲到简单工厂模式的缺点,有一点是——简单工厂模式系统难以扩展,一旦添加新产品就不得不修改简单工厂方法,这样就会造成简单工厂的实现逻辑过于复杂,然而本专题介绍的工厂方法模式可以 ...
- 设计模式(2)工厂方法模式(Factory Method)
设计模式(0)简单工厂模式 设计模式(1)单例模式(Singleton) 源码地址 0 工厂方法模式简介 0.0 工厂方法模式定义 工厂方法模式是在简单工厂模式基础上,为解决更复杂的对象创建问题而衍生 ...
随机推荐
- Train-Alypay-Cloud:蚂蚁大数据平台培训开课通知(第三次)- 培训笔记3(机器学习平台)
ylbtech-Train-Alypay-Cloud:蚂蚁大数据平台培训开课通知(第三次)- 培训笔记3(机器学习平台) 机器学习平台 一站式可视化机器学习 https://pai.cloud.ali ...
- 在Visual Studio调试器中显示Unreal的数据类型的值
转自:https://blog.csdn.net/witton/article/details/5977766 在Unreal引擎中大量使用了自定义的数据类型如:FName,FString,TArra ...
- [置顶]
Ubuntu16.04+opencv3.3.0的安装配置说明
系统环境: Linux Ubuntu 16.04 [GCC 5.4.0 20160609] on linux2 之前的教程中我们已经安装了做机器学习需要使用的框架TensorFlow,笔者本科阶段 ...
- jdbc练习demo
//连接云端服务器数据库工具类 public class TestJDBCUtil { public static String driver="com.mysql.jdbc.Driver& ...
- IO在block级别的过程分析
btt User Guide在百度找了3天没找到,bing也不行,结果google第一页第5个结果就是. 可恶的GFW http://www.fis.unipr.it/doc/blktrace-1.0 ...
- 将Hive统计分析结果导入到MySQL数据库表中(一)——Sqoop导入方式
https://blog.csdn.net/niityzu/article/details/45190787 交通流的数据分析,需求是对于海量的城市交通数据,需要使用MapReduce清洗后导入到HB ...
- 简单的自动化测试模型(python+selenium)
刚接触自动化测试,由于没有编程语言的基础,是搞不懂代码里面的函数.封装.包以及其他概念,只是了解字符串.数组.元组及字典这种最基本的名词,更不懂自动化测试框架了. ...
- OpenCL 三种内存对象的使用
▶ 包括带有 CL_MEM_READ_ONLY,CL_MEM_WRITE_ONLY,CL_MEM_READ_WRITE 标识的显示拷贝(函数 clEnqueueWriteBuffer 和 clEnqu ...
- vlc相关命令行设置
1:改变VLC模块参数 http://tianxiaoma.blog.51cto.com/1501174/309519 ====================================== ...
- javascript 对象的扩展性
javascript 对象 的可扩展性 javascript 对象中的可扩展性指的是:是否可以给对象添加新属性.所有的内置对象和自定义对象显示的都是可扩展的,对于宿主对象,则有javascript 引 ...