一、定义
定义一组算法,将每个算法都封装起来,并且使它们之间可以互换。策略模式使这些算法在客户端调用它们的时候能够互不影响地变化。(Java的TreeSet集合中,构造方法可传入具体的比较器对象以实现不同的排序算法。就是利用的策略模式)策略模式的用意是针对一组算法,将每一个算法封装到具有共同接口的独立的类中, 从而使得它们可以相互替换,使用策略模式可以把行为和环境分割开来。
二、意义
策略模式使开发人员能够开发出由许多可替换的部分组成的软件,并且各个部分之间是弱连接的关系。弱连接的特性使软件具有更强的可扩展性,易于维护;更重要的是,它大大提高了软件的可重用性。
三、角色
- 抽象策略角色:策略类,通常由一个接口或者抽象类实现。
- 具体策略角色:包装了相关的算法和行为。
- 环境角色:持有一个策略类的引用,最终给客户端调用的。
四、编写步骤
- 对策略对象定义一个公共接口。(抽象策略角色)
- 编写策略类,该类实现了上面的公共接口(具体策略角色)
- 在使用策略对象的类中保存一个对策略对象的引用。实现对策略对象的set和get方法(注入)或者使用构造方法完成赋值(环境角色)
五、代码演示
抽象策略角色
/**
* 抽象策略角色
* @author zhangkang
*
*/
public interface Strategy {
int calculate(int a, int b);
}
具体策略角色---加法
/**
* 具体策略角色---加法
* @author zhangkang
*
*/
public class AddStrategy implements Strategy {
public int calculate(int a, int b) {
return a + b;
}
}
具体策略角色---减法
/**
* 具体策略角色---减法
* @author zhangkang
*
*/
public class SubtractStrategy implements Strategy {
public int calculate(int a, int b) {
return a - b;
}
}
具体策略角色---乘法
/**
* 具体策略角色---乘法
* @author zhangkang
*
*/
public class MultiplyStrategy implements Strategy {
public int calculate(int a, int b) {
return a * b;
}
}
具体策略角色---除法
/**
* 具体策略角色---除法
* @author zhangkang
*
*/
public class DivideStrategy implements Strategy {
public int calculate(int a, int b) {
return a / b;
}
}
环境角色
/**
* 环境角色
* @author zhangkang
*
*/
public class Environment {
private Strategy strategy;
public Environment(Strategy strategy) {
this.strategy = strategy;
}
public void setStrategy(Strategy strategy) {
this.strategy = strategy;
}
public Strategy getStrategy() {
return strategy;
}
public int calculate(int a, int b) {
return strategy.calculate(a, b);
}
}
客户端测试
/**
* 客户端
* @author zhangkang
*
*/
public class Test {
public static void main(String[] args) {
int a = 6;
int b = 2;
Strategy strategy = new AddStrategy(); //创建加法策略对象
Environment e = new Environment(strategy);
System.out.println("加法:" + e.calculate(a, b));
e.setStrategy(new SubtractStrategy()); //创建减法策略对象
System.out.println("减法:" + e.calculate(a, b));
e.setStrategy(new MultiplyStrategy()); //创建乘法策略对象
System.out.println("乘法:" + e.calculate(a, b));
e.setStrategy(new DivideStrategy()); //创建除法策略对象
System.out.println("除法:" + e.calculate(a, b));
}
}
输出:
加法:8
减法:4
乘法:12
除法:3
六、缺点
1.客户端必须知道所有的策略类,并自行决定使用哪一个策略类。
2.造成很多的策略类。
可以使用工厂方法模式进行解决。