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插件制作 自增长输入框实现代码
Aug 17 jQuery
html5的自定义data-*属性和jquery的data()方法的使用示例
Aug 21 Javascript
jquery放大镜效果超漂亮噢
Nov 15 Javascript
原生js实现无缝轮播图效果
Jan 11 Javascript
Angular在模板驱动表单中自定义校验器的方法
Aug 09 Javascript
AngularJS路由删除#符号解决的办法
Sep 28 Javascript
vue的全局提示框组件实例代码
Feb 26 Javascript
Vue微信项目按需授权登录策略实践思路详解
May 07 Javascript
Vue使用watch监听一个对象中的属性的实现方法
May 10 Javascript
vue+elementui 对话框取消 表单验证重置示例
Oct 29 Javascript
flexible.js实现移动端rem适配方案
Apr 07 Javascript
JavaScript实现图片伪异步上传过程解析
Apr 10 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
用libTemplate实现静态网页的生成
2006/10/09 PHP
PHP编程中八种常见的文件操作方式
2006/11/19 PHP
php提示无法加载或mcrypt没有找到 PHP 扩展 mbstring解决办法
2012/03/27 PHP
Linux系统下使用XHProf和XHGui分析PHP运行性能
2015/12/08 PHP
JavaScript 异步调用框架 (Part 3 - 代码实现)
2009/08/04 Javascript
基于jquery ajax 用户无刷新登录方法详解
2012/04/28 Javascript
不到30行JS代码实现Excel表格的方法
2014/11/15 Javascript
使用JavaScript获取地址栏参数的方法
2014/12/19 Javascript
AngularJS入门教程之服务(Service)
2016/07/27 Javascript
jQuery-mobile事件监听与用法详解
2016/11/23 Javascript
javaScript中定义类或对象的五种方式总结
2016/12/04 Javascript
解析如何利用iframe标签以及js制作时钟
2016/12/08 Javascript
three.js实现围绕某物体旋转
2017/01/25 Javascript
JSON与JS对象的区别与对比
2017/03/01 Javascript
使用BootStrap实现标签切换原理解析
2017/03/14 Javascript
深入理解Node.js中通用基础设计模式
2017/09/19 Javascript
微信小程序列表渲染功能之列表下拉刷新及上拉加载的实现方法分析
2017/11/27 Javascript
详解最新vue-cli 2.9.1的webpack存在问题
2017/12/16 Javascript
解决angular2 获取到的数据无法实时更新的问题
2018/08/31 Javascript
在vue中读取本地Json文件的方法
2018/09/06 Javascript
JSONP原理及应用实例详解
2018/09/13 Javascript
iView-admin 动态路由问题的解决方法
2018/10/03 Javascript
利用 Chrome Dev Tools 进行页面性能分析的步骤说明(前端性能优化)
2021/02/24 Javascript
Python实现读取文件最后n行的方法
2017/02/23 Python
深入理解Python异常处理的哲学
2019/02/01 Python
Python文件打开方式实例详解【a、a+、r+、w+区别】
2019/03/30 Python
使用python实现unix2dos和dos2unix命令的例子
2019/08/13 Python
CSS3圆角和渐变2种常用功能详解
2016/01/06 HTML / CSS
优秀毕业自我鉴定
2014/02/15 职场文书
个人授权委托书范本
2014/04/03 职场文书
《灰椋鸟》教学反思
2014/04/27 职场文书
高二学年自我鉴定范文(2篇)
2014/09/26 职场文书
2015年新学期寄语
2015/02/26 职场文书
房地产公司工程部经理岗位职责
2015/04/09 职场文书
2015初一年级组工作总结
2015/07/24 职场文书
班级管理经验交流材料
2015/11/02 职场文书