JavaScript设计模式之策略模式
所谓“条条道路通罗马”,在现实中,为达到某种目的往往不是只有一种方法。比如挣钱养家:可以做点小生意,可以打分工,甚至还可以是偷、抢、赌等等各种手段。在程序语言设计中,也会遇到这种类似的情况,要实现某种功能可以有多种方案选择。比如,在很多地图类软件上,你想从A地点到达B地点时,为你提供几种交通工具的选择,可以查看每种交通工具的所需费用和时间。在程序语言设计中,把这种设计模式叫做策略模式。
策略模式的定义:策略模式是指对一系列的算法定义,并将每一个算法封装起来,而且使它们还可以相互替换。
主要解决问题:在有多种算法相似的情况下,使用 if...else 所带来的复杂和难以维护。
从上面两点可以知道,策略模式是通过定义一系列的算法,并对其进行封装,使其可以相互替换使用,目的是消除多层if...else语句嵌套的问题。这里的定义一系列的算法的意思是:你可以将每一种方案封装成函数或者是类的形式。
先看个输出今天是星期几的例子:
//获取当天是星期几函数
function getDay(day){
if(day === 0){
console.log('今天是星期日');
} if(day === 1){
console.log('今天是星期一');
} if(day === 2){
console.log('今天是星期二');
} if(day === 3){
console.log('今天是星期三');
} if(day === 4){
console.log('今天是星期四');
} if(day === 5){
console.log('今天是星期五');
} if(day === 6){
console.log('今天是星期六');
}
}; var day = new Date().getDay(); getDay(day);
上面的代码完全正常,使用起来一点问题都没有,但不易于维护。用策略模式重构上面的代码:
//定义策略类
var Strategies = (function(){ function A(){
console.log('今天是星期一');
}; function B(){
console.log('今天是星期二');
}; function C(){
console.log('今天是星期三');
}; function D(){
console.log('今天是星期四');
}; function E(){
console.log('今天是星期五');
}; function F(){
console.log('今天是星期六');
}; function G(){
console.log('今天是星期日');
}; return {
getDay1: A,
getDay2: B,
getDay3: C,
getDay4: D,
getDay5: E,
getDay6: F,
getDay0: G
} })(); //展示当天是星期几的函数
function alertWeekDay(){
var d = new Date().getDay(); //根据变量d选择调用Strategies类的方法
Strategies["getDay" + d]();
}; alertWeekDay();
大伙看到这段代码的时候,是否认为上面的代码比这个用什么策略模式的简洁的多了去了?从代码量的角度看,确实是这样。但现实是,作为开发者我们有80%的时间是在维护旧的代码,剩下的20%才是写新的代码,所以写出可维护的代码同样很重要。改用策略模式后的代码虽然代码量增加了,但更易于维护了。为什么更容易维护了呢?假如某一天W3C把Date对象的getDay()函数改成为从0~6分别对应星期一到星期日(而不是现在的0表示星期日,1~6分别对象星期一到星期六),第一段用if写的代码是不是要把所用if结构的代码都要改一遍,但第二段代码只需修改Strategies类里return的对象的方法顺序即可,那个更易于维护一眼便知。
当然上面是基于面向对象的方式使用的策略模式,大家都知道JavaScript没有类的概念,所以上面不是正在意义上的JavaScript语言策略模式。在JavaScript中,函数是一等对象,可以将函数当作一个变量传递到函数内部执行,所以JavaScript语言是天生自带策略模式的哦!下面看看真正的JavaScript语言策略模式:
function getDay0(e){
console.log('今天是星期日:' + e);
}; function getDay1(e){
console.log('今天是星期一:' + e);
}; function getDay2(e){
console.log('今天是星期二:' + e);
}; function getDay3(e){
console.log('今天是星期三:' + e);
}; function getDay4(e){
console.log('今天是星期四:' + e);
}; function getDay5(e){
console.log('今天是星期五:' + e);
}; function getDay6(e){
console.log('今天是星期六:' + e);
}; //展示备忘事件函数
function alertRemindEvents(fn, events){
fn(events);
}; alertRemindEvents(getDay3, "今天中午妈妈没时间做饭,我要自己去买菜做饭了。");
策略模式的优缺点:
优点: 1、算法可以自由切换。 2、避免使用多重条件判断。 3、扩展性良好。
缺点: 1、策略类会增多。 2、所有策略类都需要对外暴露。
JavaScript设计模式之策略模式的更多相关文章
- JavaScript设计模式之策略模式(学习笔记)
在网上搜索“为什么MVC不是一种设计模式呢?”其中有解答:MVC其实是三个经典设计模式的演变:观察者模式(Observer).策略模式(Strategy).组合模式(Composite).所以我今天选 ...
- JavaScript设计模式(策略模式)
策略模式的定义是:定义一系列的算法,把它们一个个封装起来,并且使它们可以相互替换.将不变的部分和变化的部分隔开是每个设计模式的主题,策略模式也不例外,策略模式的目的就是将算法的使用与算法的实现分离开来 ...
- 第二章 --- 关于Javascript 设计模式 之 策略模式
这一章节里面,我们会主要的针对JavaScript中的策略模式进行理解和学习 一.定义 策略模式: 定义一系列的算法,把他们封装起来,并且是他们可以相互替换. (这样的大的定义纲领,真的不好理解,特别 ...
- 再起航,我的学习笔记之JavaScript设计模式20(策略模式)
策略模式 策略模式(Strategy):将定义的一组算法封装起来,使其相互之间可以替换.封装的算法具有一定的独立性,不会随客户端变化而变化. 其实策略模式在我们生活中可应用的地方还是比较多的,比如在商 ...
- JavaScript设计模式_02_策略模式
在程序设计中,我们常常遇到这种情况,要实现某一个功能我们有很多种算法可以实现.这些算法灵活多样,而且可以随意互相替换.这种解决方案就是所谓的策略模式. /* * pre:策略模式 * 示例:公司计算奖 ...
- JavaScript设计模式之策略模式【组合委托】
前言:语言只是工具,思想才是核心 今天要总结的是 策略模式 策略在开发中的应用非常广泛,所以也是非常常见且使用的设计模式. 在实际开发中,往往在实现一个功能时,有多种解决方案可行. 常见场景: 解压: ...
- javascript设计模式:策略模式
前言 策略模式有效利用组合.委托.多态等技术和思想,可以有效避免多重条件选择语句. 策略模式对开放-封闭原则提供了很好的支持,将算法封装在strategy中,使得他们易于切换.理解.扩展. 策略模式中 ...
- 理解javascript中的策略模式
理解javascript中的策略模式 策略模式的定义是:定义一系列的算法,把它们一个个封装起来,并且使它们可以相互替换. 使用策略模式的优点如下: 优点:1. 策略模式利用组合,委托等技术和思想,有效 ...
- 设计模式:策略模式(Strategy)
定 义:它定义了算法家族,分别封装起来,让它们之间可以互相替换,此模式让算法的变化, 不会影响到使用算法的客户. 示例:商场收银系统,实现正常收费.满300返100.打8折.......等不同收费 ...
随机推荐
- java判断网页的编码格式
在爬取内容时,遇到乱码问题.故需对网页内容编码格式做判断,方式大体分为三种:一.从header标签中获取Content-Type=#Charset:二.从meta标签中获取Content-Type=# ...
- 开发JQuery插件(转)
教你开发jQuery插件(转) 阅读目录 基本方法 支持链式调用 让插件接收参数 面向对象的插件开发 关于命名空间 关于变量定义及命名 压缩的好处 工具 GitHub Service Hook 原 ...
- shell中数组讲解
定义数组 在Shell中,用括号来表示数组,数组元素用"空格"符号分割开.定义数组的一般形式为: 代码如下: 数组名=(值1 值2 ... 值n) 例如: 代码如下: array_ ...
- 浅谈WPF依赖项属性
浅谈WPF依赖项属性 0. 引言 依赖项属性虽然在使用上和CLR属性一样,但是它是WPF特有的,不同于CLR属性.只是封装为我们常用CLR的属性,在语法使用上和CLR属性一样.WPF中一些功能:动画, ...
- 安装RRDtool 1.4.5
安装rrdtoolRrdtool安装需要cairo.libxml2.pango库支持,可通过yum安装安装libart_lgpl-devel这个包yum -y install libart_lgpl- ...
- ABP官方文档翻译 6.1.3 异常处理
处理异常 介绍 启用错误处理 Non-Ajax请求 显示异常 UserFriendlyException Error模型 AJAX请求 异常事件 介绍 此文档是与ASP.NET MVC和Web API ...
- SSD trim及4k对齐
trim可以帮助减小SSD的写放大WA问题,删除文件后不仅仅是将文件标记为删除,而是在SSD空闲的时候统一进行删除. Linux下的trim支持叫discard,修改fstab文件,在挂载参数中加上d ...
- HTTP面试题都在这里
HTTP常见面试题 Http与Https的区别: Http与Https的区别: HTTP 的URL 以http:// 开头,而HTTPS 的URL 以https:// 开头 HTTP 是不安全的,而 ...
- Maven项目中的配置文件找不到以及打包问题
我们在使用maven开发项目的时候,创建model的时候会自动创建一个resource目录:这个目录是用来放配置文件的,我们把配置文件放在这个目录中项目打包才会将配置文件打包进去. 有的时候我们会把配 ...
- linux目录结构 简单讲解
1./- 根每一个文件和目录从根目录开始.只有root用户具有该目录下的写权限.请注意,/root是root用户的主目录,这与/.不一样 2./bin中 - 用户二进制文件包含二进制可执行文件.在单用 ...