一、定义
针对某个问题,根据其所处的不同环境,有不同的一组算法,将每一个算法封装到具有共同接口的独立类中,从而可以是它们在不影响客户端的情况下进行相互替换。
二、策略模式的组成
抽象策略角色:由一个接口或者抽象类实现,次角色给出所有策略类需要实现的接口
具体策略对象:包装了相关的算法和行为
环境角色:持有一个抽象策略类的引用,用于客户端调用策略类
三、结构图
图片转自他人博客
四、代码
//抽象策略接口
public interface Strategy{
//相关的算法
void algorithm();
}
//具体的策略类
public class ConcreteStrategyA implements Strategy{
public void algorithm(){
//第一种实现
}
}
//具体的策略类
public class ConcreteStrategyB implements Strategy{
public void algorithm(){
//第二种实现
}
}
//环境类
public class Context{
//持有抽象策略类的引用
private Strategy strategy;
//利用构造方法传入具体的策略类对象
public Context(Strategy strategy){
this.strategy = strategy;
}
//调用策略类对象的方法啊
public void algorithm(){
strategy.algorithm();
}
}
public class Main{
public static void main(String[] args){
Strategy strategyA = new ConcreteStrategyA();
Strategy strategyB = new ConcreteStrategyB();
//根据传入的不同策略类对象客户端执行不同的算法,当有新的算法是,只需要再写一个策略类即可,不影响其他类
Context contextA = new Context(startegyA);
Context contextB = new Context(strategyB);
contextA.algorithm();
contextB.algorithm();
}
}
六、优点与缺点
优点:
- 策略模式提供了管理相关算法族的方法
- 策略模式提供了可以替换继承关系的方法
- 策略模式避免了使用多重条件转移语句(多重转移语句不易维护)
缺点:
- 客户端必须知道所有策略类,并自行决定使用哪一策略类
- 策略模式会造成项目中有大量策略类
七、JDK中对于策略模式的实践
Comparator接口就是对策略模式的实践
public interface Comparator<T>{
int compare(T o1, T o2);
//其余方法省略,JDK1.8之后其余方法均有了默认实现,子类可以不重写
}
任何实现了Comparator接口的类都必须实现compare方法,Comparator接口就是策略模式中的抽象策略类,而compare()方法就是封装的算法。在进行排序比较的过程中,我们只需要传入实现了Comparator接口的类的实例,不必考虑具体算法的实现过程。