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 相关文章推荐
ExtJS 2.0 实用简明教程之布局概述
Apr 29 Javascript
一些常用的JS功能函数代码
Jun 23 Javascript
window.open打开页面居中显示的示例代码
Dec 27 Javascript
extJS中常用的4种Ajax异步提交方式
Mar 07 Javascript
js实现的Easy Tabs选项卡用法实例
Sep 06 Javascript
JavaScript学习笔记整理_用于模式匹配的String方法
Sep 19 Javascript
JavaScript中localStorage对象存储方式实例分析
Jan 12 Javascript
bootstrap按钮插件(Button)使用方法解析
Jan 13 Javascript
微信小程序上传图片到服务器实例代码
Nov 07 Javascript
nuxt配置通过指定IP和端口访问的实现
Jan 08 Javascript
微信小程序swiper组件实现抖音翻页切换视频功能的实例代码
Jun 24 Javascript
记一次vue跨域的解决
Oct 21 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/02 无线电
PHP Try-catch 语句使用技巧
2016/02/28 PHP
在Laravel框架里实现发送邮件实例(邮箱验证)
2016/05/20 PHP
php异步:在php中使用fsockopen curl实现类似异步处理的功能方法
2016/12/10 PHP
php+redis实现多台服务器内网存储session并读取示例
2017/01/12 PHP
php从数据库中获取数据用ajax传送到前台的方法
2018/08/20 PHP
dess中一个简单的多路委托的实现
2010/07/20 Javascript
js取滚动条的尺寸的函数代码
2011/11/30 Javascript
JQuery 实现在同一页面锚点链接之间的平滑滚动
2014/10/29 Javascript
JavaScript 实现完美兼容多浏览器的复制功能代码
2015/04/28 Javascript
使用 JavaScript 进行函数式编程 (一) 翻译
2015/10/02 Javascript
深入JavaScript高级程序设计之对象、数组(栈方法,队列方法,重排序方法,迭代方法)
2015/12/01 Javascript
js实现商品抛物线加入购物车特效
2020/11/18 Javascript
javascript显示倒计时控制按钮的简单实现
2016/06/07 Javascript
js实现点击切换checkbox背景图片的简单实例
2017/05/08 Javascript
node实现定时发送邮件的示例代码
2017/08/26 Javascript
浅谈使用React.setState需要注意的三点
2017/12/18 Javascript
vue项目部署到Apache服务器中遇到的问题解决
2018/08/24 Javascript
微信小程序动态显示项目倒计时
2019/06/20 Javascript
详解微信小程序支付流程与梳理
2019/07/16 Javascript
使用vue-router切换页面时实现设置过渡动画
2019/10/31 Javascript
Vue 一键清空表单的实现方法
2020/02/07 Javascript
Vue 构造选项 - 进阶使用说明
2020/08/14 Javascript
python根据距离和时长计算配速示例
2014/02/16 Python
python编写弹球游戏的实现代码
2018/03/12 Python
详解python的argpare和click模块小结
2019/03/31 Python
Django 数据库同步操作技巧详解
2019/07/19 Python
python将unicode和str互相转化的实现
2020/05/11 Python
Python图像识别+KNN求解数独的实现
2020/11/13 Python
zooplus德国:便宜地订购动物用品、动物饲料、动物食品
2020/05/06 全球购物
餐饮收银员岗位职责
2014/02/07 职场文书
就业意向书范文
2014/04/01 职场文书
小学教师师德承诺书
2014/05/23 职场文书
学术研讨会欢迎词
2015/01/26 职场文书
《自然之道》读后感3篇
2019/12/17 职场文书
python数据分析之单因素分析线性拟合及地理编码
2022/06/25 Python