策略模式
定义: 定义了一组算法,将每个算法都封装起来,并且使他们之间相互转换
类型: 行为类模式
类图:
通过类图可以看出通过访问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