1.什么是策略模式
定义一组算法,将每个算法都封装起来,并且使它们之间可以互换。
2.什么时候使用策略模式
例:如果实现一个计算器功能 首先我们会定义一个exec的方法并且传入a,b两个为int值的参数及一个运算符参数(目前只实现加减不考虑参数null值问题)
public int exec(int a,int b,String operation){
if("+".equals(operation)){
return a+b;
}else if("-".equals(operation)){
return a-b;
}
}
以上是不用设计模式我们的编码方式 此代码可维护性差,下面介绍策略模式实现加减计算
先看类图(此图来自设计模式之禅——"策略模式通用类图")
首先我们来定义一个Calculate接口 接口内定义一个计算方法
public interface Calculate {
int exec(int a,int b);
}
然后分别定义加法类和减法类实现Calculate接口
public class Add implements Calculate{
@Override
public int exec(int a, int b) {
return a+b;
}
}
public class Sub implements Calculate {
@Override
public int exec(int a, int b) {
return a-b;
}
}
最后定义一个Context类并将计算接口依赖到构造方法中
public class Context {
private Calculate calculate;
public Context(Calculate calculate){
this.calculate = calculate;
}
public int exec(int a,int b){
return this.calculate.exec(a,b);
}
}
测试
首先创建一个Context对象并且将计算接口的任意一个实现类传入构造方法中
public static void main(String[] args) {
//普通策略模式加法测试
int addValue = new Context(new Add()).exec(1,2);
System.out.println("AddValue :"+addValue);
//普通策略模式加法测试
int subValue = new Context(new Sub()).exec(2,1);
System.out.println("subValue :"+subValue);
}
}
得出计算结果
AddValue :3
subValue :1
3.扩展(枚举策略)
还以上面场景为例使用枚举的方式解决
首先定义一个抽象的方法exec,然后在每个枚举成员中进行实现
package strategy.EnumeStrategy;
/**
* JC2
*/
public enum StrategyEnum {
//加法
ADD("+"){
@Override
public int exec(int a,int b){
return a+b;
}
},
//减法
SUB("-"){
@Override
public int exec(int a,int b){
return a-b;
}
};
//抽象函数
public abstract int exec (int a,int b);
public String value = "";
StrategyEnum(String value){
this.value = value;
}
//获取枚举成员值“+||-”
public String getValue() {
return this.value;
}
}
测试
/**
* JC2
*/
public class TestMain {
public static void main(String[] args) {
int strategyEnumAddValue = StrategyEnum.ADD.exec(1,2);
String add = StrategyEnum.ADD.getValue();
System.out.println("当前运算符号 :"+add);
System.out.println("计算结果为 :"+strategyEnumAddValue);
}
}
总结:
1.普通策略模式
优点:
1.算法可以自由切换
2.避免使用多重条件判断
3.扩展性良好
缺点:
1.策略类数量增多,每一个策略都是一个类,复用的可能性很小,类数量增多。
2.所有的策略类都需要对外暴露
使用场景:
多个类只有在算法或行为上稍有不同的场景
算法需要自由切换的场景
需要屏蔽算法规则的场景
注意:
如果系统中的一个策略家族的具体策略数量超过4个,则需要考虑使用混合模式,解决
策略类膨胀和对外暴露的问题
2.枚举策略
优点:
更简洁且更符合面向对象思想(对a和b进行加法运算(ADD),并立刻执行(exec))
注意:
受枚举类型的限制,每个枚举项都是public、final、static的,扩展性受到了一定的约束,因此在系统开发中,策略枚举一般担当不经常发生变化的角色