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 相关文章推荐
Mootools 1.2教程 设置和获取样式表属性
Sep 15 Javascript
js获取事件源及触发该事件的对象
Oct 24 Javascript
jQuery实现购物车多物品数量的加减+总价计算
Jun 06 Javascript
vue2.0父子组件及非父子组件之间的通信方法
Jan 21 Javascript
javascript阻止事件冒泡和浏览器的默认行为
Jan 21 Javascript
值得分享和收藏的xmlplus组件学习教程
May 05 Javascript
使用Fullpage插件快速开发整屏翻页的页面
Sep 13 Javascript
微信小程序使用request网络请求操作实例
Dec 15 Javascript
boostrap模态框二次弹出清空原有内容的方法
Aug 10 Javascript
vue props传值失败 输出undefined的解决方法
Sep 11 Javascript
在Vue中使用icon 字体图标的方法
Jun 14 Javascript
前端开发基础javaScript的六大作用
Aug 06 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
摩卡咖啡
2021/03/03 咖啡文化
php 3行代码的分页算法(求起始页和结束页)
2009/10/21 PHP
优化php效率,提高php性能的一些方法
2011/03/24 PHP
PHP网页游戏学习之Xnova(ogame)源码解读(十二)
2014/06/25 PHP
php页面,mysql数据库转utf-8乱码,utf-8编码问题总结
2015/08/27 PHP
php array_reverse 以相反的顺序返回数组实例代码
2017/04/11 PHP
PHP实现网站应用微信登录功能详解
2019/04/11 PHP
Javascript中常见的校验如域名、手机、邮箱等等
2014/01/02 Javascript
JS判断浏览器是否支持某一个CSS3属性的方法
2014/10/17 Javascript
Node.js中Request模块处理HTTP协议请求的基本使用教程
2016/03/31 Javascript
Jquery修改image的src属性,图片不加载问题的解决方法
2016/05/17 Javascript
Nodejs多站点切换Htpps协议详解及简单实例
2017/02/23 NodeJs
react-router实现按需加载
2017/05/09 Javascript
深入理解ES6 Promise 扩展always方法
2017/09/26 Javascript
jQuery实现所有验证通过方可提交的表单验证
2017/11/21 jQuery
JS检测浏览器开发者工具是否打开的方法详解
2020/10/02 Javascript
[50:05]VGJ.S vs OG 2018国际邀请赛淘汰赛BO3 第二场 8.22
2018/08/23 DOTA
python抓取最新博客内容并生成Rss
2015/05/17 Python
Python编程之event对象的用法实例分析
2017/03/23 Python
详解 Python 读写XML文件的实例
2017/08/02 Python
利用python爬取斗鱼app中照片方法实例
2017/12/03 Python
python类的方法属性与方法属性的动态绑定代码详解
2017/12/27 Python
django自带的server 让外网主机访问方法
2018/05/14 Python
深入浅析Python传值与传址
2018/07/10 Python
python地震数据可视化详解
2019/06/18 Python
Python 离线工作环境搭建的方法步骤
2019/07/29 Python
Python如何使用Gitlab API实现批量的合并分支
2019/11/27 Python
PyQt5的相对布局管理的实现
2020/08/07 Python
python 调用Google翻译接口的方法
2020/12/09 Python
Talbots官网:美国成熟女装品牌
2019/11/15 全球购物
如何写好升职自荐信
2014/01/06 职场文书
护理专科毕业生自荐书范文
2014/02/19 职场文书
环境保护建议书
2014/08/26 职场文书
详解JS数组方法
2021/11/20 Javascript
python图像处理 PIL Image操作实例
2022/04/09 Python
vue递归实现树形组件
2022/07/15 Vue.js