策略+职责模式学习以及思考

146 阅读2分钟

策略模式学习以及思考

策略模式来帮助我们解决哪些问题?什么场景下适合使用策略模式?

  1. 策略模式可以帮助我们解决算法的灵活切换问题。
  2. 策略模式可以帮助我们解决业务逻辑的复杂度问题。
  3. 策略模式可以帮助我们解决代码耦合的问题。

策略模式的核心思想是什么?

  1. 策略模式的核心思想就是将算法单独封装起来,通过上下文对象来调用不同的算法。
  2. 策略模式可以帮助我们解耦业务逻辑和算法实现之间的关系,提高代码的可维护性和可扩展性。

策略模式的应用场景有哪些?

  1. 策略模式的应用场景非常广泛,比如:
  2. 电商系统中,不同用户的优惠活动策略不同。
  3. 游戏系统中,不同角色的攻击方式策略不同。
  4. 金融系统中,不同银行的贷款利率策略不同。

上面说的几个场景,如果按照常规模式下去编写,那一堆堆堆 if else 代码叠在一起估计是避免不来,如果把逻辑判断和业务内容写在一起,维护起来也是非常痛苦的。

策略模式帮我们解决这个问题,将算法和业务逻辑解耦,让代码更加清晰、可维护、可扩展。

思路大概就是这样了, 记录下学习中的几个点

after 和 before 函数,在策略模式中,before 函数是用来做前置判断的,after 是用来做后置处理的。

Function.prototype.after = function( fn ){ 
    var self = this; 
    return function(){ 
        var ret = self.apply( this, arguments ); 
        if ( ret === 'nextSuccessor' ){ 
            return fn.apply( this, arguments ); 
        } 
        return ret; 
    } 
};
var order = order500yuan.after( order200yuan ).after( orderNormal );

先看下这个 after 函数, 接收一个fn, self 指向调用它的order500yuan 对象,返回一个函数。执行返回函数时, 先执行 order500yuan 对象,如果返回值是 nextSuccessor, 就执行 fn 函数。 否则返回 执行的结果。

联想下 before 函数的写法, 也是接收一个函数 fn, self 指向调用它的order500yuan 对象,返回一个函数。执行返回函数时, 先执行 fn 函数,

Function.prototype.before = function( fn ){ 
    var self = this; 
    return function(){
        var ret = fn.apply( this, arguments );  
        if ( ret === 'nextSuccessor' ){ 
            return self.apply( this, arguments );
        } 
        return ret; 
    } 
};

下面是一个职责链 的写法

var Chain = function( fn ){ 
 this.fn = fn; 
 this.successor = null; 
}; 
Chain.prototype.setNextSuccessor = function( successor ){ 
 return this.successor = successor; 
}; 
Chain.prototype.passRequest = function(){ 
 var ret = this.fn.apply( this, arguments ); 
 if ( ret === 'nextSuccessor' ){ 
 return this.successor && this.successor.passRequest.apply( this.successor, arguments ); 
 } 
 return ret; 
}; 
现在我们把 3 个订单函数分别包装成职责链的节点:
var chainOrder500 = new Chain( order500 ); 
var chainOrder200 = new Chain( order200 ); 
var chainOrderNormal = new Chain( orderNormal ); 
然后指定节点在职责链中的顺序:
chainOrder500.setNextSuccessor( chainOrder200 ); 
chainOrder200.setNextSuccessor( chainOrderNormal );