javascript设计模式详解之策略模式
接上篇命令模式来继续看下js设计模式中另一种常用的模式,策略模式。策略模式也是js开发中常用的一种实例,不要被这么略显深邃的名字给迷惑了。接下来我们慢慢看一下。
一、基本概念与使用场景:
基本概念:定义一系列方法,封装起来使他们可以相互替换。也就是将策略封装在策略类中,当发起请求时管理类将请求委托给对应策略类。
概括而言,就是讲对应不同情况的策略(即不同的处理方法)专门分装在一个对象中,即策略对象里面包含所有的策略。事件请求不直接请求该策略对象,而是有个管理对象来处理请求转发给策略对象的不同接口,这里其实也可以认为涉及到代理模式的概念,不过要申明一点,任何的设计模式都不是单一独立存在的,一种解决方案涉及到两种或者多种的设计模式也是很正常的现象。不要去强行区分到底属于哪种设计模式。 主要目的是为了避免太多的逻辑判断语句的出现,解耦业务逻辑和算法策略。
使用场景:适用于业务逻辑中重复比较多依赖参数或者标识来区分不同的处理的场景。例如react中一个新建某个订单的页面中,存在很多的渲染input等。
二、实例:
假设我们现在有这样一个需求:需要根据form表单元素的不同类型,当点击的时候输出对应的表单元素类型。
分析一下其实很简单,不外乎这下面的几种做法:。
1、简单粗暴流、每个元素都绑定一个事件,依次处理就好:
/**
* 每个元素绑定一个事件,分别去输出
*/
btn1.onClick(function(){
console.log('btn1 type')
})
//n多个
btnN.onClick(function(){
console.log('btnN type')
})
2、上面的代码太糟心了,例如10个input就要写10个事件来绑定。可以绑定在同一个事件上,通过判断来处理
1)给各个表单绑定事件,点击的时候将type属性带过去(这个就略过了)
2)针对性的处理事件,用if-else或者switch来判断
/**
* 非策略模式
* 根据入参的不同,调用不同的方法,输出对应结果
*/
var renderDom = function(type){
if(type == 'text'){
console.log('this is method for text')
}else if(type == 'radio'){
console.log('this is method for radio')
}else if(type == 'checkbox'){
console.log('this is method for checkbox')
}else {
console.log('this is method for default')
}
//也可能这么写
switch(type){
case 'text':
console.log('this is method for text')
break;
case 'radio':
console.log('this is method for radio')
/**
* 余下的省略
* */
}
}
3、上面这种写法引入了那么多的逻辑判断,当有更改的时候就需要跟进不同的方法里进行修改了。还是有点麻烦。这时候就可以用策略模式来做了:
/**
* 针对不同情况的策略算法封装在策略类fucs中,
* 从调用事件中去除繁琐的if或者switch逻辑判断。达到解耦的目的
* 加入后面再增加‘select’的选项增加对应的方法即可
*/
var funcs = {
text:function(){
console.log('this is method for text')
},
radio:function(){
console.log('this is method for radio')
},
checkbox:function(){
console.log('this is method for checkbox')
},
default:function(){
console.log('this is method for default')
}
}
var renderDom = function(type){
/**
* 只需要根据不同的入参,自行匹配策略类中的接口即可。
*/
return (funcs[type] || funcs['default'])()
}
renderDom('checkbox')
简单说下策略模式的思路:
1)所谓的策略对象就是funcs对象,里面的不同属性接口对应的方法就是策略。与逻辑判断分离开,如果有不同的情况的出现,对应的增加属性接口即可。
2)renderDom方法就是对应的管理类了,只需要根据不同的type,去调用funcs不同的方法就好了。如果有改动,这里不需要修改,为了健壮性考虑,如果type没有对应的接口,那就调用默认的default对应接口。
3)调用事件,就保持不变。将tyoe类型传过去就好了。
这样来看,将可变的策略部分封装成了一个对象,不再需要逻辑判断只需要调用策略类对应的接口就行,这样无论从性能,可读性,可扩展性上来讲都比逻辑判好的不是一点半点。
至此策略模式也介绍结束了。可能我们在原来写代码的过程中多多少少的都用到过,只不过没有明确的名称观念罢了。说开了,设计模式也就是为了解决问题而产生的一种思路,没有听起来那么的高大上。切勿为了使用设计模式而强行引入,也切勿不同情况坚持使用某一种设计模式。不要被形式总之快速高效的解决问题才是我们的唯一目的。
相关内容:
参考文章:JavaScript设计模式与开发实践
javascript设计模式详解之策略模式的更多相关文章
- javascript设计模式详解之命令模式
每种设计模式的出现都是为了弥补语言在某方面的不足,解决特定环境下的问题.思想是相通的.只不过不同的设计语言有其特定的实现.对javascript这种动态语言来说,弱类型的特性,与生俱来的多态性,导致某 ...
- Javascript设计模式详解
Javascript常用的设计模式详解 阅读目录 一:理解工厂模式 二:理解单体模式 三:理解模块模式 四:理解代理模式 五:理解职责链模式 六:命令模式的理解: 七:模板方法模式 八:理解javas ...
- JavaScript设计模式与开发实践 - 策略模式
引言 本文摘自<JavaScript设计模式与开发实践> 在现实中,很多时候也有多种途径到达同一个目的地.比如我们要去某个地方旅游,可以根据具体的实际情况来选择出行的线路. 如果没有时间但 ...
- Javascript设计模式学习三(策略模式)
定义:定义一系列的算法,把它们一个个封装起来,并且使它们可以互相替换.目的:将算法的使用和算法的实现分离开来.比如: if(input == 'A'){ return 1; } if(input == ...
- JavaScript设计模式(三) - 策略模式
什么是策略模式? 策略模式支持在运行时由使用者选择合适的算法,对于使用者而言不用关心背后的具体实现,由使用者自动根据当前程序执行的上下文和配置,从已有的算法列列表中选择出合适的算法来处理当前任务. ...
- JavaScript设计模式 样例二 —— 策略模式
策略模式(Strategy Pattern): 定义:定义了一族算法: 封装了每个算法: 这族的算法可互换代替. 目的:将算法的使用与算法的实现分离开来. 场景:可用来消除大量的条件分支语句. 例:J ...
- Java常用设计模式详解1--单例模式
单例模式:指一个类有且仅有一个实例 由于单例模式只允许有一个实例,所以单例类就不可通过new来创建,而所有对象都默认有一个无参的构造函数可以创建对象,所以单例类不仅不能提供public的构造方法,还需 ...
- Javascript常用的设计模式详解
Javascript常用的设计模式详解 阅读目录 一:理解工厂模式 二:理解单体模式 三:理解模块模式 四:理解代理模式 五:理解职责链模式 六:命令模式的理解: 七:模板方法模式 八:理解javas ...
- 设计模式详解及PHP实现:代理模式
[目录] 代理模式(Proxy pattern) 代理模式是一种结构型模式,它可以为其他对象提供一种代理以控制对这个对象的访问. 主要角色 抽象主题角色(Subject):它的作用是统一接口.此角色定 ...
随机推荐
- mysql创建数据表时如何判断是否已经存在?
>>> create table if not exists people(name text,age int(2),gender char(1)); 如上代码表示创建一个名为peo ...
- 使用cmd命令打开Python文件式程序方法
首先:需要确定已编好的Python程序的存储路径:(即在哪个磁盘,哪个文件中) 其次:打开cmd命令,输入该程序所在磁盘,敲回车键:(例如其存储在E盘,则输入“E:”,敲回车键.) 然后:输入pyth ...
- 串的模式匹配和KMP算法
在对字符串的操作中,我们经常要用到子串的查找功能,我们称子串为模式串,模式串在主串中的查找过程我们成为模式匹配,KMP算法就是一个高效的模式匹配算法.KMP算法是蛮力算法的一种改进,下面我们先来介绍蛮 ...
- C#中ListView易错的方法
现在有一个ListView(lv1),有2列. ListViewItem lvi = new ListViewItem(); lvi.Text = "语文"; lvi.SubIte ...
- SQL条件循环语句以及异常知识整理
create or replace procedure pr_test1 is begin > then dbms_output.put_line('条件成立'); elsif > the ...
- 老李推荐:第8章7节《MonkeyRunner源码剖析》MonkeyRunner启动运行过程-小结
老李推荐:第8章7节<MonkeyRunner源码剖析>MonkeyRunner启动运行过程-小结 poptest是国内唯一一家培养测试开发工程师的培训机构,以学员能胜任自动化测试,性 ...
- Ackerman 函数 (双递归函数)
public static int ackerman(int n,int m){ if(n==1&&m==0){return 2;} else if(n==0&&m ...
- TaintDroid简介
1.Information-Flow tracking,Realtime Privacy Monitoring.信息流动追踪,实时动态监控. 2.TaintDroid是一个全系统动态污点跟踪和分析系统 ...
- Python 装饰器装饰类中的方法
title: Python 装饰器装饰类中的方法 comments: true date: 2017-04-17 20:44:31 tags: ['Python', 'Decorate'] categ ...
- Android 正则表达式验证手机号、姓名(包含少数民族)、身份证号
最近项目中新增的功能,需要对手机号.姓名.身份证号等一些信息进行验证,最好的方法是通过正则表达式来验证,网上查了一些资料,写了这几个工具方法. 1.验证手机号 规则:第一位只能是1,第二位为3-8中的 ...