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 相关文章推荐
jQuery 表单验证扩展代码(一)
Oct 11 Javascript
上传的js验证(图片/文件的扩展名)
Apr 25 Javascript
JS实现在网页中弹出一个输入框的方法
Mar 03 Javascript
数据分析软件之FineReport教程:[5]参数界面JS(全)
Aug 13 Javascript
jquery捕捉回车键及获取checkbox值与异步请求的方法
Dec 24 Javascript
javascript html实现网页版日历代码
Mar 08 Javascript
AngularJS中ng-class用法实例分析
Jul 06 Javascript
详解Angular-cli生成组件修改css成less或sass的实例
Jul 27 Javascript
详谈js对url进行编码和解码(三种方式的区别)
Aug 16 Javascript
React BootStrap用户体验框架快速上手
Mar 06 Javascript
详解关于React-Router4.0跳转不置顶解决方案
May 10 Javascript
layui 对table中的数据进行转义的实例
Sep 12 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或asp创建网页桌面快捷方式的代码
2010/03/23 PHP
第4章 数据处理-php字符串的处理-郑阿奇(续)
2011/07/04 PHP
php中用加号与用array_merge合并数组的区别深入分析
2013/06/03 PHP
file_get_contents(&quot;php://input&quot;, &quot;r&quot;)实例介绍
2013/07/01 PHP
JavaScript 密码强度判断代码
2009/09/05 Javascript
JavaScript实现大数的运算
2014/11/24 Javascript
jQuery实现统计输入文字个数的方法
2015/03/11 Javascript
jQuery-mobile事件监听与用法详解
2016/11/23 Javascript
JS判断是否为JSON对象及是否存在某字段的方法(推荐)
2016/11/29 Javascript
详解AngularJS ng-class样式切换
2017/06/27 Javascript
Vue+Element UI+Lumen实现通用表格分页功能
2019/02/02 Javascript
详解在React-Native中持久化redux数据
2019/05/22 Javascript
jQuery实现鼠标移入显示蒙版效果
2020/01/11 jQuery
python调用shell的方法
2013/11/20 Python
Python探索之pLSA实现代码
2017/10/25 Python
TF-IDF与余弦相似性的应用(一) 自动提取关键词
2017/12/21 Python
Python代码生成视频的缩略图的实例讲解
2019/12/22 Python
如何基于线程池提升request模块效率
2020/04/18 Python
python中K-means算法基础知识点
2021/01/25 Python
浅谈利用缓存来优化HTML5 Canvas程序的性能
2015/05/12 HTML / CSS
维珍澳洲航空官网:Virgin Australia
2017/09/08 全球购物
意大利领先的线上奢侈品销售电商:Eleonora Bonucci
2017/10/17 全球购物
Roxy荷兰官方网站:冲浪、滑雪板、服装和配件
2019/10/22 全球购物
乡镇干部先进事迹材料
2014/02/03 职场文书
会计专业应届生自荐信
2014/02/07 职场文书
天猫某品牌专卖店运营计划书
2014/03/21 职场文书
书香家庭事迹材料
2014/05/09 职场文书
见习报告格式要求
2014/11/04 职场文书
2014年文员工作总结
2014/11/18 职场文书
2014年内部审计工作总结
2014/12/09 职场文书
异地恋情人节寄语
2015/02/28 职场文书
可怜妈妈观后感
2015/06/09 职场文书
爱国影片观后感
2015/06/18 职场文书
进行数据处理的6个 Python 代码块分享
2022/04/06 Python
JavaScript中10个Reduce常用场景技巧
2022/06/21 Javascript
java.util.NoSuchElementException原因及两种解决方法
2022/06/28 Java/Android