深入理解JavaScript系列(28):设计模式之工厂模式详解


Posted in Javascript onMarch 03, 2015

介绍

与创建型模式类似,工厂模式创建对象(视为工厂里的产品)时无需指定创建对象的具体类。

工厂模式定义一个用于创建对象的接口,这个接口由子类决定实例化哪一个类。该模式使一个类的实例化延迟到了子类。而子类可以重写接口方法以便创建的时候指定自己的对象类型。

这个模式十分有用,尤其是创建对象的流程赋值的时候,比如依赖于很多设置文件等。并且,你会经常在程序里看到工厂方法,用于让子类类定义需要创建的对象类型。

正文

下面这个例子中,是应用了工厂方法对第26章构造函数模式代码的改进版本:

var Car = (function () {

    var Car = function (model, year, miles) {

        this.model = model;

        this.year = year;

        this.miles = miles;

    };

    return function (model, year, miles) {

        return new Car(model, year, miles);

    };

})();
var tom = new Car("Tom", 2009, 20000);

var dudu = new Car("Dudu", 2010, 5000);

不好理解的话,我们再给一个例子:

var productManager = {};
productManager.createProductA = function () {

    console.log('ProductA');

}
productManager.createProductB = function () {

    console.log('ProductB');

}

        

productManager.factory = function (typeType) {

    return new productManager[typeType];

}
productManager.factory("createProductA");

如果还不理解的话,那我们就再详细一点咯,假如我们想在网页面里插入一些元素,而这些元素类型不固定,可能是图片,也有可能是连接,甚至可能是文本,根据工厂模式的定义,我们需要定义工厂类和相应的子类,我们先来定义子类的具体实现(也就是子函数):

var page = page || {};

page.dom = page.dom || {};

//子函数1:处理文本

page.dom.Text = function () {

    this.insert = function (where) {

        var txt = document.createTextNode(this.url);

        where.appendChild(txt);

    };

};
//子函数2:处理链接

page.dom.Link = function () {

    this.insert = function (where) {

        var link = document.createElement('a');

        link.href = this.url;

        link.appendChild(document.createTextNode(this.url));

        where.appendChild(link);

    };

};
//子函数3:处理图片

page.dom.Image = function () {

    this.insert = function (where) {

        var im = document.createElement('img');

        im.src = this.url;

        where.appendChild(im);

    };

};

那么我们如何定义工厂处理函数呢?其实很简单:

page.dom.factory = function (type) {

    return new page.dom[type];

}

使用方式如下:
var o = page.dom.factory('Link');

o.url = 'http://www.cnblogs.com';

o.insert(document.body);

至此,工厂模式的介绍相信大家都已经了然于心了,我就不再多叙述了。

总结

什么时候使用工厂模式

以下几种情景下工厂模式特别有用:

1.对象的构建十分复杂
2.需要依赖具体环境创建不同实例
3.处理大量具有相同属性的小对象

什么时候不该用工厂模式

不滥用运用工厂模式,有时候仅仅只是给代码增加了不必要的复杂度,同时使得测试难以运行下去。

Javascript 相关文章推荐
基于jquery的DIV随滚动条滚动而滚动的代码
Jul 20 Javascript
JS解决ie6下png透明的方法实例
Aug 02 Javascript
javascript为下拉列表动态添加数据项
May 23 Javascript
Python脚本后台运行的几种方式
Mar 09 Javascript
jQuery的bind()方法使用详解
Jul 15 Javascript
jQuery flip插件实现的翻牌效果示例【附demo源码下载】
Sep 20 Javascript
Seajs是什么及sea.js 由来,特点以及优势
Oct 13 Javascript
NPM 安装cordova时警告:npm WARN deprecated minimatch@2.0.10: Please update to minimatch 3.0.2 or higher to
Dec 20 Javascript
微信小程序 利用css实现遮罩效果实例详解
Jan 21 Javascript
js 实现复选框只能选择一项的示例代码
Jan 23 Javascript
详解Vue中的基本语法和常用指令
Jul 23 Javascript
vue中上传视频或图片或图片和文字一起到后端的解决方法
Dec 01 Javascript
JS运动基础框架实例分析
Mar 03 #Javascript
jQuery DOM插入节点操作指南
Mar 03 #Javascript
JS运动框架之分享侧边栏动画实例
Mar 03 #Javascript
jQuery DOM删除节点操作指南
Mar 03 #Javascript
JS实现表格数据各种搜索功能的方法
Mar 03 #Javascript
深入理解JavaScript系列(27):设计模式之建造者模式详解
Mar 03 #Javascript
javascript验证身份证号
Mar 03 #Javascript
You might like
phpize的深入理解
2013/06/03 PHP
深入理解PHP变量的值类型和引用类型
2015/10/21 PHP
Yii2 rbac权限控制之菜单menu实例教程
2016/04/28 PHP
示例详解Laravel重置密码代码重构
2016/08/10 PHP
利用php_imagick实现复古效果的方法
2016/10/18 PHP
THinkPHP获取客户端IP与IP地址查询的方法
2016/11/14 PHP
DEFER怎么用?
2006/07/01 Javascript
JavaScript实现当网页加载完成后执行指定函数的方法
2015/03/21 Javascript
jQuery插件简单实现方法
2015/07/18 Javascript
jQuery的each循环用法简单示例
2016/06/12 Javascript
AngularJS实现分页显示数据库信息
2016/07/01 Javascript
学习vue.js表单控件绑定操作
2016/12/05 Javascript
js实现下一页页码效果
2017/03/07 Javascript
vue轮播图插件vue-awesome-swiper
2017/11/27 Javascript
vue中倒计时组件的实例代码
2018/07/06 Javascript
vue添加axios,并且指定baseurl的方法
2018/09/19 Javascript
vue中子组件传递数据给父组件的讲解
2019/01/27 Javascript
微信小程序学习笔记之登录API与获取用户信息操作图文详解
2019/03/29 Javascript
vue+导航锚点联动-滚动监听和点击平滑滚动跳转实例
2019/11/13 Javascript
浅谈JavaScript中的“!!”作用
2020/08/03 Javascript
[06:45]DOTA2卡尔工作室 英雄介绍幻影长矛手篇
2013/07/12 DOTA
python网络编程学习笔记(六):Web客户端访问
2014/06/09 Python
python使用calendar输出指定年份全年日历的方法
2015/04/04 Python
Python中decorator使用实例
2015/04/14 Python
用Python中的wxPython实现最基本的浏览器功能
2015/04/14 Python
PyQT实现多窗口切换
2018/04/20 Python
python实现linux下抓包并存库功能
2018/07/18 Python
python实现websocket的客户端压力测试
2019/06/25 Python
django多个APP的urls设置方法(views重复问题解决)
2019/07/19 Python
python3的UnicodeDecodeError解决方法
2019/12/20 Python
如果NULL和0作为空指针常数是等价的,那我到底该用哪一个
2014/09/16 面试题
大学生四个方面的自我评价
2013/09/19 职场文书
大学生入党积极分子自我评价
2014/09/20 职场文书
勤俭节约倡议书范文
2015/04/29 职场文书
Go语言实现Base64、Base58编码与解码
2021/07/26 Golang
用Python可视化新冠疫情数据
2022/01/18 Python