前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >行为型模式之策略模式

行为型模式之策略模式

作者头像
RobinsonZhang
发布2018-12-24 14:07:01
3070
发布2018-12-24 14:07:01
举报

前言

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

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

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

策略模式

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

场景应用

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

代码语言:javascript
复制
function return30(price){

}

function return50(price){

}

然后开始了switch

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

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

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

价格策略对象

代码语言:javascript
复制
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的动画函数。

其调用过程是这样的:

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

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

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

代码语言:javascript
复制
// 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;
    }
};

表单验证

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

代码语言:javascript
复制
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来解决这个问题。
本文参与 腾讯云自媒体分享计划,分享自作者个人站点/博客。
原始发表:2018-12-07,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 前言
  • 策略模式
  • 场景应用
  • 然后开始了switch
  • 价格策略对象
  • jq延伸拓展
  • 表单验证
  • 总结
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档