设计模式-策略模式

277 阅读2分钟

策略模式

定义: 定义了一组算法,将每个算法都封装起来,并且使他们之间相互转换

类型: 行为类模式

类图:

通过类图可以看出通过访问Context来访问实际的算法,实际开发中如果算法中存在重复逻辑代码可以将Strategy定义为抽象类,毕竟设计的目的是为了减少重复代码。

策略模式的结构:

封装类: 也叫上下文,对策略进行二次封装,目的是避免高层模块对策略的直接调用

抽象策略:

通常情况下为一个接口,当各个实现类中存在着重复的逻辑时,则使用抽象类来封装这部分公共的代码,此时,策略模式看上去更像是模版方法模式。

具体策略: 具体策略角色通常由一组封装了算法的类来担任,这些类之间可以根据需要自由替换

//策略接口
public interface Strategy {


    //统计总的价格
    double algorithmInterface();

}

//策略算法A
 class ConcreteStrategyA implements Strategy {

    private double price;

    public ConcreteStrategyA(double price){
        this.price = price;
    }

    @Override
    public double algorithmInterface() {

        return this.price;
    }
}
//策略算法B
class ConcreteStrategyB implements Strategy{


    private double moneyCondition;

    private double moneyReturn;

    public ConcreteStrategyB(double moneyCondition ,double moneyReturn){

        this.moneyCondition = moneyCondition;
        this.moneyReturn = moneyReturn;
    }

    @Override
    public double algorithmInterface() {
        return moneyCondition * moneyReturn;
    }

}
//策略算法c
 class ConcreteStrategyC implements Strategy {


    private double moneyCondition;

    private double moneyReturn;

    private double money;

    @Override
    public double algorithmInterface() {

        if(money >= moneyCondition){
            return money -  moneyReturn;
        }
        return money;
    }

 
}


/**
 * 策略类调用环境
 */
 class ContextStrategy {


    private Strategy strategy;
    
    public Strategy  contextInterface(Strategy strategy){

        return this.strategy = strategy;
    }

    public void execute(){
        strategy.algorithmInterface();
    }

}



策略模式的优缺点

优点:

  • 由于实现同一个抽象,所有可以自由转换
  • 易于扩展,只需要实现同一个接口就可以增加相应的策略

缺点:

  • 策略维护问题,如果策略算法过多维护起来比较繁琐
  • 使用策略模式的场景 调用方 与算法方必须是透明的,如果不明白的话, 策略的实现也是没有意义的

适用场景

做面向对象设计的策略模式实质上就是面向对象中的继承和多态,在看完策略模式的通用代码后,我想,即使之前从来没有听说过策略模式,在开发过程中也一定使用过它吧?至少在在以下两种情况下,大家可以考虑使用策略模式,

几个类的主要逻辑相同,只在部分逻辑的算法和行为上稍有区别的情况。 有几种相似的行为,或者说算法,客户端需要动态地决定使用哪一种,那么可以使用策略模式,将这些算法封装起来供客户端调用。 策略模式是一种简单常用的模式,我们在进行开发的时候,会经常有意无意地使用它,一般来说,策略模式不会单独使用,跟模版方法模式、工厂模式等混合使用的情况比较多。


参考资料:w3c