1、策略模式解析
策略模式定义了一系列算法,分别封装起来,让他们之间可以相互替换,此模式让算法的变化,不会影响到使用算法的客户。通过策略模式可以减少通过if..else语句来切换相似算法,降低复杂度和维护难度。
优点:
- 简化单元测试,因为每个算法类都有自己的类。
- 减少算法类和使用算法类之间的耦合。
使用场景:
- 策略模式用来封装算法,但是也可以用它来封装几乎任何类型的规则,只要在分析过程中听到需要在不同时间应用不同的业务规则,就可以考虑使用策略模式处理这种变化的可能性。
- 如果在一个系统里面有许多类,它们之间的区别仅在于它们的行为,那么使用策略模式可以动态地让一个对象在许多行为中选择一种行为。
- 一个系统需要动态地在几种算法中选择一种。
- 如果一个对象有很多的行为,如果不用恰当的模式,这些行为就只好使用多重的条件选择语句来实现。 (参考:https://www.runoob.com/design-pattern/strategy-pattern.html)
2、类图
3、java 基本实现
策略类(Strategy):定义所有的公共接口
//策略类
public abstract class Strategy {
//一个公共接口
public abstract int AlgorithmInterface();
}
多个封装了具体算法或行为的类,继承自策略类(Strategy)
//具体的策略实现1
public class ConcreteStrategyA extends Strategy {
@Override
public int AlgorithmInterface() {
//计算逻辑A
System.out.println("算法A");
return 0;
}
}
//具体的策略实现1
public class ConcreteStrategyB extends Strategy {
@Override
public int AlgorithmInterface() {
//计算逻辑B
System.out.println("算法B");
return 0;
}
}
//具体的策略实现3
public class ConcreteStrategyC extends Strategy {
@Override
public int AlgorithmInterface() {
//计算逻辑C
System.out.println("算法C");
return 0;
}
}
Context :用一个具体的Strategy来配置(初始化)
//维护一个Strategy对象的引用
public class Context {
private Strategy strategy = null;
public Context(Strategy strategy) {
this.strategy = strategy;
}
public int ContextInterface() {
return strategy.AlgorithmInterface();
}
}
客户端使用:根据不同的入参调用不同的方法。
public class Main {
public static void main(String[] args) {
Context context = new Context(new ConcreteStrategyA());
context.ContextInterface();
context = new Context(new ConcreteStrategyC());
context.ContextInterface();
}
}
思考:策略模式和简单工厂模式的区别?
这两种设计模式看起来区别不大,都是一个抽象的算法类,然后从抽象类继承实现具体的算法或行为。区别是简单工厂设计模式通过一个工厂类负责对象的创建,而策略模式通过Context上下文来维护Strategy对象的引用。
在算法易变的商场打折问题中,使用简单工厂模式必将频繁的修改工厂类;而使用策略模式需要客户端控制使用哪一个具体策略类(算法)。
注:更加详细的介绍请阅读《大话设计模式》