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 相关文章推荐
CSS常用网站布局实例
Apr 03 Javascript
用JavaScript调用WebService的示例
Apr 07 Javascript
Javascript 检测键盘按键信息及键码值对应介绍
Jan 03 Javascript
JQuery以JSON方式提交数据到服务端示例代码
May 05 Javascript
纯js实现无限空间大小的本地存储
Jun 18 Javascript
jQuery中的通配符选择器使用总结
May 30 Javascript
Vue.js双向绑定操作技巧(初级入门)
Dec 27 Javascript
JavaScript Canvas绘制圆形时钟效果
Aug 20 Javascript
js实现鼠标单击Tab表单切换效果
May 16 Javascript
详解vuex 渐进式教程实例代码
Nov 27 Javascript
微信小程序+云开发实现欢迎登录注册
May 24 Javascript
JavaScript手写数组的常用函数总结
Nov 22 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中数组首字符过滤功能代码
2012/07/31 PHP
php报错502badgateway解决方法
2019/10/11 PHP
一个刚完成的layout(拖动流畅,不受iframe影响)
2007/08/17 Javascript
jQuery - css() 方法示例详解
2014/01/16 Javascript
js 调用百度地图api并在地图上进行打点添加标注
2014/05/13 Javascript
jQuery实现的Div窗口震动特效
2014/06/09 Javascript
原创jQuery弹出层插件分享
2015/04/02 Javascript
浅谈javascript中return语句
2015/07/15 Javascript
js验证真实姓名与身份证号是否匹配
2015/10/13 Javascript
js判断文本框输入的内容是否为数字
2015/12/23 Javascript
详解JS: reduce方法实现 webpack多文件入口
2017/02/14 Javascript
详解http访问解析流程原理
2017/10/18 Javascript
浅谈v-for 和 v-if 并用时筛选条件方法
2019/11/07 Javascript
vue.js 实现a标签href里添加参数
2019/11/12 Javascript
微信小程序实现点击按钮后修改颜色
2019/12/05 Javascript
JavaScript获取当前url路径过程解析
2019/12/27 Javascript
vue2.x 对象劫持的原理实现
2020/04/19 Javascript
浅谈vue使用axios的回调函数中this不指向vue实例,为undefined
2020/09/21 Javascript
Nuxt 项目性能优化调研分析
2020/11/07 Javascript
python使用mysqldb连接数据库操作方法示例详解
2013/12/03 Python
Python中的True,False条件判断实例分析
2015/01/12 Python
python正则表达式re之compile函数解析
2017/10/25 Python
查看django版本的方法分享
2018/05/14 Python
pyqt5中QThread在使用时出现重复emit的实例
2019/06/21 Python
python 将日期戳(五位数时间)转换为标准时间
2019/07/11 Python
Python3 列表,数组,矩阵的相互转换的方法示例
2019/08/05 Python
基于Tensorflow高阶读写教程
2020/02/10 Python
Python实现石头剪刀布游戏
2021/01/20 Python
CSS3悬停效果案例应用
2012/11/21 HTML / CSS
深入剖析webstorage[html5的本地数据处理]
2016/07/11 HTML / CSS
nohup的用法
2012/11/26 面试题
构造方法和其他方法的区别
2016/04/26 面试题
迟到检讨书400字
2014/01/13 职场文书
2014年小学数学工作总结
2014/12/12 职场文书
教师正风肃纪心得体会
2016/01/15 职场文书
Win11远程连接不上怎么办?Win11远程桌面用不了的解决方法
2022/08/05 数码科技