行为型模式之策略模式

栏目: 后端 · 发布时间: 5年前

内容简介:在讲解策略模式之前,我们了解下行为型设计模式。那么行为型是什么意思呢?主要场景是什么呢?行为型设计模式主要是用于不同对象之间职责划分或者算法抽象,行为型设计模式不仅仅涉及类和对象,还涉及类或者对象之间的交流模式并加以实现。感谢作者张容铭对本模式的讲解,非常透彻清晰,我只是一个搬运工,做好自己的学习实践,谨记:他山之石,可以攻玉。

在讲解策略模式之前,我们了解下行为型设计模式。那么行为型是什么意思呢?主要场景是什么呢?

行为型 设计模式 主要是用于不同对象之间职责划分或者算法抽象,行为型设计模式不仅仅涉及类和对象,还涉及类或者对象之间的交流模式并加以实现。

感谢作者张容铭对本模式的讲解,非常透彻清晰,我只是一个搬运工,做好自己的学习实践,谨记:他山之石,可以攻玉。

策略模式

策略模式是把一系列的算法封装起来,让其可以相互替换,封装的算法具有一定的独立性,不随客户端的变化而变化。

场景应用

马上到圣诞节了,老板要让你做一款活动的促销活动,根据用户不同等级给与不同的返现。然后你就开始下面这样写了

function return30(price){
    
}

function return50(price){
    
}
复制代码

然后开始了switch

我相信不少人都会这样写,没什么问题,能工作,看上去维护性也很好。

但好像你忘掉了什么,这只是一堆零散的代码啊,我还需要做的是: 1 如何把不同的打折返现模式封装起来 2 如何根据不同情况去使用我想要的,很明显目前的方式是不行的,因为目前的函数是暴露在全局的。如果我另外的位置需要还需要写这么一堆switch语句。

switch(user.cheaperLevel){
    case return30 :  return30(price);
    break;
    case return60 :  return60(price);
    break;
}
复制代码

价格策略对象

const PriceStrategy = function(){
// 内部算法对象
    const stragtegy = {
       return30:function(price){
        },
       return60:function(price){
        },
    }
// 策略算法调用接口
   return function(cheaperLevel,price){
       return stragtegy[cheaperLevel] && stragtegy[cheaperLevel](price)
   }
}

// 使用方式
let price = PriceStrategy('return30','321.56')
console.log(price)
复制代码

小结:这样实现之后,我们在使用时只要关注如何调用而不用关注原来的算法;而负责算法的人也可以统筹所有的算法策略,通过策略的api暴露的方式提供给使用者。

jq延伸拓展

jq中的策略模式使用案例,相信你一定使用jq的animate的动画函数。

其调用过程是这样的:

$("div").animate({width:300px},1000,'linear')
$("div").animate({width:300px},1000,'swing')
复制代码

通过一个关键字我们就可以调用其内部封装的30种动画,而不用关心其内部实现。

追本溯源,我们定位到jq的源码:

// line 660-667 https://github.com/jquery/jquery/blob/2.0.0/src/effects.js
jQuery.easing = {
	linear: function( p ) {
		return p;
	},
	swing: function( p ) {
		return 0.5 - Math.cos( p*Math.PI ) / 2;
	}
};
复制代码

表单验证

除了上面的,其实我们工作中复杂常用的表单验证也可以用这个设计模式轻松实现,甚至我们还可以根据自己的需要去为其增加策略。

const inputStrategy = () => {
    const strategy = {
        notNull : (val) => {
            return /\s+/.test(val) ? '请输入' : '';
        },
        number :(val) => {
            return val.isNaN ? '请输入数字' :'';
        }
    }
    return {
        check:(type,value)=>{
           return  strategy[type](value) ;
        },
        // 肯定策略不够用,为它添加一个自定义的策略Api
        addStrategy:(type,fn)=>{
            strategy[type] = fn ;
        }
    }
}

// 算法调用
let inputValue = document.getElmentById('target');
let isVaild = inputStrategy.check('number',inputValue);
复制代码

总结

虽然好像说的很明白了,但好像你觉得并没有和开始的分支语句有什么区别,那么我把区别重点说明下。

  • 将算法单独维护在策略对象里,负责算法的人不用关心具体业务使用;而业务方只要负责调用即可;
  • 通过对算法的封装实现了对算法的引用,避免了重复;
  • 策略模式也是分支语句的一种优化技巧,目的也是为了让其更加可维护。如果你觉得你的分支语句上升不到策略的高度完全可以用switch来解决这个问题。

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持 码农网

查看所有标签

猜你喜欢:

本站部分资源来源于网络,本站转载出于传递更多信息之目的,版权归原作者或者来源机构所有,如转载稿涉及版权问题,请联系我们

ES6标准入门(第3版)

ES6标准入门(第3版)

阮一峰 / 电子工业出版社 / 2017-9 / 99.00

ES6是下一代JavaScript语言标准的统称,每年6月发布一次修订版,迄今为止已经发布了3个版本,分别是ES2015、ES2016、ES2017。本书根据ES2017标准,详尽介绍了所有新增的语法,对基本概念、设计目的和用法进行了清晰的讲解,给出了大量简单易懂的示例。本书为中级难度,适合那些已经对JavaScript语言有一定了解的读者,可以作为学习这门语言最新进展的工具书,也可以作为参考手册......一起来看看 《ES6标准入门(第3版)》 这本书的介绍吧!

在线进制转换器
在线进制转换器

各进制数互转换器

HTML 编码/解码
HTML 编码/解码

HTML 编码/解码

Base64 编码/解码
Base64 编码/解码

Base64 编码/解码