javascript设计模式 – 简单工厂模式原理与应用实例分析
作者:李小强 发布时间:2023-08-27 19:53:20
本文实例讲述了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>
这样当我做新增时,只需要要新增一条配置即可,不用去对公告内容做修改。满足了开关原则的对扩展支持对修改关闭。
简单工厂模式总结:
优点:
* 简单工厂模式实现了对象创建和使用的分离
缺点:
* 工厂模式集中了所有产品的创建逻辑,职责过重,一旦出现问题会影响到整个系统
适用场景:
* 适用于创建的对象比较少,由于创建的对象较少,不会造成工厂方法中的业务逻辑太过复杂
* 客户端只知道传入工厂类的参数,对于如何创建对象并不关心
希望本文所述对大家JavaScript程序设计有所帮助。
来源:http://www.isjs.cn/?p=950


猜你喜欢
- 分享炫酷的前端页面随机二维码验证,供大家参考,具体内容如下直接上代码<%@ page contentType="text/h
- 我有两个继承一个基类的Django模型:- Request- Inquiry- Analysis请求有两个外键到内置用户模型。create_
- 简单使用最开始,我们用最短的代码体验一下logging的基本功能。import logginglogger = logging.getLog
- 一、前言本来写了脚本用于暴力破解密码,可是1秒钟尝试一个密码2220000个密码我的天,想用多线程可是只会一个for全开,难道开222000
- 有时表或结果集包含重复的记录。有时它是允许的,但有时它需要停止重复的记录。有时它需要识别重复的记录从表中删除。本章将介绍如何防止发生在一个表
- 耦合两个或以上的体系或两种运动形式间相互作用而彼此影响以至于联合起来的现象。在软件工程中,对象之间的耦合度就是对象之间的依赖性,对象之间的耦
- 摘要在上一篇文章,时间日期处理的入门里面,我们简单介绍了一下载pandas里对时间日期的简单操作。下面将补充一些常用方法。时间日期的比较假设
- 1、路径https://www.lfd.uci.edu/~gohlke/pythonlibs/PS:网上说有时候报404,解决办法是换浏览器
- 本来在网上有不少关于这方面的文章,可是我找了好久也没看到把(可能我的搜索水平有线把)不过倒是聊天室的很多。如何统计会员再线状态,希望对刚开始
- 前言本文目的:根据本人的习惯与理解,用最简洁的表述,介绍爬虫的定义、组成部分、爬取流程,并讲解示例代码。基础爬虫的定义:定向抓取互联网内容(
- 在项目中遇到一情况让困扰了半天,同一张PNG8图片为何部份图标在IE6中消失呢?当时一度怀疑是cache或hosts问题反反复复开关浏览器结
- 最近在改一个页面,原来的编码是gb2312,为了国际化,改成utf-8,开始时浏览还是正常。因为电脑偶感小恙,于是恢复了系统,这才发现改后的
- 今天成功把易语言调用验证码通杀的DLL在Python中成功调用了特此共享出来,下面是识别截图:识别方法1:"""
- 我插入Mysql5的中文一直是乱码。但是直接使用mysqlAdmin,EMS等工具插入DB就不是乱码。而且我还可以使用程序正常地读出来。原因
- 一、背景:在平时工作中有遇到端口检测,查看服务端特定端口是否对外开放,常用nmap,tcping,telnet等,同时也可以利用站长工具等w
- 我就废话不多说了,大家还是直接看代码吧~package mainimport ("encoding/json""
- 程序运算时往往需要数据,而数据的IO又往往需要时间传输,而常见的串行处理,是一个任务处理完成才接着处理新的任务, 其效率低下可想而知。 假如
- 我们可以利用err对象来判断。当程序没有出现错误就说明已经执行了sql操作: sql="insert into
- 本文实例讲述了Python接收Gmail新邮件并发送到gtalk的方法。分享给大家供大家参考。具体实现方法如下:#!/usr/bin/env
- 本文介绍了Vue2 SSR 缓存 Api 数据,分享给大家,具体如下:1. 安装缓存依赖: lru-cachenpm install lru