javascript设计模式 ? 简单工厂模式原理与应用实例分析


Posted in Javascript onApril 09, 2020

本文实例讲述了javascript设计模式 ? 简单工厂模式。分享给大家供大家参考,具体如下:

介绍:简单工厂模式是最常用的一类创建型设计模式。其中简单工厂模式并不属于GoF23个经典设计模式,它通常被作为学习其他工厂模式的基础。

定义:定义一个工厂类,它可以根据参数的不同返回不同的实例,被创建的实例通常都具有相同的父类,因为在简单工厂模式中创建实例的方法是静态方法,因此简单工厂模式又被称为静态工厂方法模式,它属于类创建型模式。

场景:我们需要写一个dialog工具类,在项目初期我们只需要考虑一个简单的弹窗实现,项目持续迭代,会衍生出各种类型的弹窗,带关闭按钮的,带确认按钮的…..

我见到最多的做法是根据一个type值来判断当前需要弹什么类型的窗口,这样的设计我之前没觉得有问题,但是看了前面介绍的设计原则,我们也来分析下这么做的缺点:

1. 存在多个if…else…代码块,代码冗长,阅读困难,维护困难,测试困难,影响系统性能。
2. dialog类职责过重,负责初始化所有弹窗实例,违反了单一职责原则,不利于重用和维护。
3. 当需要新增弹窗类型是,必须修改源代码,违反了开关原则。
4. 不同种类弹窗基础样式相同,会导致存在大量重复代码。
5. 各类弹窗的创建和使用都是在各个业务逻辑中,如果我想修改创建方式必须修改所有业务代码,违反了开关原则

示例:

var Dialog = (function(){
  var createNotice = function(){
    return '<div>notice</div>';
  }
  var createToast = function(){
    return '<div>toast</div>';
  }
  var createWarnin = function(){
 return '<div>warnin</div>';
  }
  var Dialog = function(){
 this.element = '';
 this.name = '';
 this.show = function(){
   console.log(this.name + ' is show -> ' + this.element);
 };
  }
 
  return {
 factory: function(arg){
   var _dialog;
   if(arg === 'notice'){
     _dialog = new Dialog();
     _dialog.element = createNotice();
     _dialog.name = 'notice';
     }else if(arg === 'toast'){
     _dialog = new Dialog();
     _dialog.element = createToast();
     _dialog.name = 'toast';
   }else if(arg === 'warnin'){
     _dialog = new Dialog();
     _dialog.element = createWarnin();
     _dialog.name = 'warnin';
   }
   return _dialog;
 }
  }
})();
 
var notice = Dialog.factory('notice');
var toast = Dialog.factory('toast');
var warnin = Dialog.factory('warnin');
toast.show(); //toast is show -> <div>toast</div>
notice.show(); //notice is show -> <div>notice</div>
warnin.show(); //warnin is show -> <div>warnin</div>

以上的解决方案是自己理解着写的,对照着java的示例写了一个,实现的方式有很多种,你可以用原型链,用继承来实现都可以。我们这里主要讨论下为什么要这么写。

之前我们列出了5个缺点:我们主要解决了2,4和5,将共有的方法属性抽取出来写在父类上,减少了重复代码,将每种情况特有的代码抽取出来,解决了不符合单一职责原则的问题。

重要的是将所有弹窗的创建集中在工厂类中,当有修改时,只需要修改工厂类即可,不会影响业务代码。

这里我们思考一下:1.如何去掉那些if…else…? 2.当我要新增一个error类型的弹窗时如何满足开关原则?

我自己试了一下:

var Dialog = function(){
  this.element = '';
  this.name = '';
  this.show = function(){
 console.log(this.name + ' is show -> ' + this.element);
  };
}
 
Dialog.createNotice = function(){ return '<div>notice</div>'; };
Dialog.createToast = function(){ return '<div>toast</div>'; };
Dialog.createWarnin = function(){ return '<div>warnin</div>'; };
Dialog.factory = function(arg){ 
  var _dialog = new Dialog();
  _dialog.element = Dialog[arg]();
  _dialog.name = arg;
  return _dialog;
};
 
var notice = Dialog.factory('createNotice');
var toast = Dialog.factory('createToast');
var warnin = Dialog.factory('createWarnin');
notice.show(); //createNotice is show -> <div>notice</div>
warnin.show(); //createWarnin is show -> <div>warnin</div>
toast.show(); //createToast is show -> <div>toast</div>

这样当我做新增时,只需要要新增一条配置即可,不用去对公告内容做修改。满足了开关原则的对扩展支持对修改关闭。

简单工厂模式总结:

优点:
* 简单工厂模式实现了对象创建和使用的分离

缺点:
* 工厂模式集中了所有产品的创建逻辑,职责过重,一旦出现问题会影响到整个系统

适用场景:
* 适用于创建的对象比较少,由于创建的对象较少,不会造成工厂方法中的业务逻辑太过复杂
* 客户端只知道传入工厂类的参数,对于如何创建对象并不关心

感兴趣的朋友可以使用在线HTML/CSS/JavaScript代码运行工具:http://tools.3water.com/code/HtmlJsRun测试上述代码运行效果。

希望本文所述对大家JavaScript程序设计有所帮助。

Javascript 相关文章推荐
Js动态创建div
Sep 25 Javascript
js动态添加onload、onresize、onscroll事件(另类方法)
Dec 26 Javascript
javascript中的原型链深入理解
Feb 24 Javascript
js语法学习之判断一个对象是否为数组
May 13 Javascript
jquery+ajax验证不通过也提交表单问题处理
Dec 12 Javascript
js实现接收表单的值并将值拼在表单action后面的方法
Nov 23 Javascript
js事件驱动机制 浏览器兼容处理方法
Jul 23 Javascript
Vue组件化通讯的实例代码
Jun 23 Javascript
JavaScript条件判断_动力节点Java学院整理
Jun 26 Javascript
JavaScript之Canvas_动力节点Java学院整理
Jul 04 Javascript
Vue框架里使用Swiper的方法示例
Sep 20 Javascript
js String.prototype.trim字符去前后空格的扩展
Aug 23 Javascript
javascript设计模式 ? 单例模式原理与应用实例分析
Apr 09 #Javascript
微信小程序纯文本实现@功能
Apr 08 #Javascript
JavaScript 俄罗斯方块游戏实现方法与代码解释
Apr 08 #Javascript
vue与iframe之间的信息交互的实现
Apr 08 #Javascript
Javascript摸拟自由落体与上抛运动原理与实现方法详解
Apr 08 #Javascript
antd-mobile ListView长列表的数据更新遇到的坑
Apr 08 #Javascript
详解element上传组件before-remove钩子问题解决
Apr 08 #Javascript
You might like
PHP基础之运算符的使用方法
2013/04/28 PHP
基础的WordPress插件制作教程
2015/11/24 PHP
使用一个for循环将N*N的二维数组的所有值置1实现方法
2017/05/29 PHP
用js实现的仿sohu博客更换页面风格(简单版)
2007/03/22 Javascript
Javascript客户端将指定区域导出到Word、Excel的代码
2008/10/22 Javascript
JS分割字符串并放入数组的函数
2011/07/04 Javascript
了不起的node.js读书笔记之mongodb数据库交互
2014/12/22 Javascript
JavaScript常用脚本汇总(二)
2015/03/04 Javascript
Bootstrap Table使用整理(五)之分页组合查询
2017/06/09 Javascript
详解vue-cli 脚手架项目-package.json
2017/07/04 Javascript
weex里Vuex state使用storage持久化详解
2017/09/09 Javascript
vue+swiper实现组件化开发的实例代码
2017/10/26 Javascript
详解Vue路由钩子及应用场景(小结)
2017/11/07 Javascript
React BootStrap用户体验框架快速上手
2018/03/06 Javascript
原生JS实现前端本地文件上传
2018/09/08 Javascript
layui 富文本图片上传接口与普通按钮 文件上传接口的例子
2019/09/23 Javascript
Python操作json数据的一个简单例子
2014/04/17 Python
深入理解python中的闭包和装饰器
2016/06/12 Python
pandas使用get_dummies进行one-hot编码的方法
2018/07/10 Python
python 命名规范知识点汇总
2020/02/14 Python
pandas读取csv文件提示不存在的解决方法及原因分析
2020/04/21 Python
Python实现迪杰斯特拉算法过程解析
2020/09/18 Python
Python list和str互转的实现示例
2020/11/16 Python
使用CSS3编写灰阶滤镜来制作黑白照片效果的方法
2016/05/09 HTML / CSS
Brora官网:英国领先的羊绒服装品牌
2019/08/28 全球购物
武汉世纪畅想数字传播有限公司 .NET笔试题
2015/06/13 面试题
如何为DataGridView添加一个定制的Column Type
2014/01/21 面试题
大学生个人推荐信范文
2013/11/25 职场文书
六个一活动实施方案
2014/03/21 职场文书
小学二年级评语
2014/04/21 职场文书
人力资源管理系自荐信
2014/05/31 职场文书
学校组织向国旗敬礼活动方案(中小学适用)
2014/09/27 职场文书
2015年班级工作总结范文
2015/04/03 职场文书
任命书格式模板
2015/09/22 职场文书
python 使用Tensorflow训练BP神经网络实现鸢尾花分类
2021/05/12 Python
python中Matplotlib绘制直线的实例代码
2021/07/04 Python