接上篇命令模式来继续看下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设计模式详解之策略模式的更多相关文章

  1. javascript设计模式详解之命令模式

    每种设计模式的出现都是为了弥补语言在某方面的不足,解决特定环境下的问题.思想是相通的.只不过不同的设计语言有其特定的实现.对javascript这种动态语言来说,弱类型的特性,与生俱来的多态性,导致某 ...

  2. Javascript设计模式详解

    Javascript常用的设计模式详解 阅读目录 一:理解工厂模式 二:理解单体模式 三:理解模块模式 四:理解代理模式 五:理解职责链模式 六:命令模式的理解: 七:模板方法模式 八:理解javas ...

  3. JavaScript设计模式与开发实践 - 策略模式

    引言 本文摘自<JavaScript设计模式与开发实践> 在现实中,很多时候也有多种途径到达同一个目的地.比如我们要去某个地方旅游,可以根据具体的实际情况来选择出行的线路. 如果没有时间但 ...

  4. Javascript设计模式学习三(策略模式)

    定义:定义一系列的算法,把它们一个个封装起来,并且使它们可以互相替换.目的:将算法的使用和算法的实现分离开来.比如: if(input == 'A'){ return 1; } if(input == ...

  5. JavaScript设计模式(三) - 策略模式

    什么是策略模式? 策略模式支持在运行时由使用者选择合适的算法,对于使用者而言不用关心背后的具体实现,由使用者自动根据当前程序执行的上下文和配置,从已有的算法列列表中选择出合适的算法来处理当前任务.   ...

  6. JavaScript设计模式 样例二 —— 策略模式

    策略模式(Strategy Pattern): 定义:定义了一族算法: 封装了每个算法: 这族的算法可互换代替. 目的:将算法的使用与算法的实现分离开来. 场景:可用来消除大量的条件分支语句. 例:J ...

  7. Java常用设计模式详解1--单例模式

    单例模式:指一个类有且仅有一个实例 由于单例模式只允许有一个实例,所以单例类就不可通过new来创建,而所有对象都默认有一个无参的构造函数可以创建对象,所以单例类不仅不能提供public的构造方法,还需 ...

  8. Javascript常用的设计模式详解

    Javascript常用的设计模式详解 阅读目录 一:理解工厂模式 二:理解单体模式 三:理解模块模式 四:理解代理模式 五:理解职责链模式 六:命令模式的理解: 七:模板方法模式 八:理解javas ...

  9. 设计模式详解及PHP实现:代理模式

    [目录] 代理模式(Proxy pattern) 代理模式是一种结构型模式,它可以为其他对象提供一种代理以控制对这个对象的访问. 主要角色 抽象主题角色(Subject):它的作用是统一接口.此角色定 ...

随机推荐

  1. Tcl与Design Compiler (九)——综合后的形式验证

    本文属于原创手打(有参考文献),如果有错,欢迎留言更正:此外,转载请标明出处 http://www.cnblogs.com/IClearner/  ,作者:IC_learner 这里来讲一下forma ...

  2. Spring整合Struts2,Hibernate的xml方式

    作为一个学习中的码农,一直学习才是我们的常态,所以最近学习了SSH(Spring,Struts2,Hibernate)整合,数据库用的MySQL. 写了一个简单的例子,用的工具是IntelliJ Id ...

  3. poptest老李谈数据结构中深度优先和广度优先

    poptest是国内唯一一家培养测试开发工程师的培训机构,以学员能胜任自动化测试,性能测试,测试工具开发等工作为目标.如果对课程感兴趣,请大家咨询qq:908821478,咨询电话010-845052 ...

  4. 性能调优之MYSQL高并发优化下

    三.算法的优化 尽量避免使用游标,因为游标的效率较差,如果游标操作的数据超过1万行,那么就应该考虑改写..使用基于游标的方法或临时表方法之前,应先寻找基于集的解决方案来解决问题,基于集的方法通常更有效 ...

  5. 1.Java集合总结系列:Java集合概述

    一.概述 集合是 Java 中非常重要的 API,在实际应用中非常广泛,在许多面试中也是必考的知识点. Java 所有集合类都位于 java.util 包下,Java 的集合只能保存对象,而无法保存保 ...

  6. zoom动画,实现图片点击预览效果

    参考:https://developer.android.google.cn/training/animation/zoom.html 1.创建Views 下面的布局包括了你想要zoom的大版本和小版 ...

  7. NPM(Node.js) 使用介绍

    前言:express 推出了4.X,自己尝试了一下,出现了各种问题.结果查看了各种文档和问题,现在在这个给大家分享下4.X版本的安装. NPM 使用介绍 NPM是随同NodeJS一起安装的包管理工具, ...

  8. mysql 免安装版 + sqlyog 安装 步骤 --- 发的有点晚

    总有些朋友不会安装mysql,其实软件安装不是学习mysql的重点,基本上也就安装一次,工作后一般公司里也不会让你安装,如果非要安装,百度一下就行了.安装版本百度上有许多,下面就提供一个免安装版的步骤 ...

  9. STM32学习笔记(三)——外部中断的使用

    开发板芯片:STM32F407ZGT6 硬件连接:PE3-KEY1 一.STM32F4的中断介绍 STM32F4的每个IO都可以作为外部中断输入,很强大的功能吧!以前学习的51只有两个外部中断. ST ...

  10. java OJ题目判断输入结束(与C语言的EOF结束等价)

    /* * java 作Oj题目是会有输入若干数据的情况,不好判断输入结束符, * 类似于C语言中的EOF符号 * 在这里提供了一种方法 * */ import java.util.Iterator; ...