策略模式
策略模式定义了算法家族,分别封装起来,让他们之间可以互相转换,这个模式的算法变化,不会影响到使用算法的客户。
结构图
其中,Context对象以聚合的方式,拥有Strategy对象。
-w790
代码实现
1、创建基类或者接口
public abstract class Strategy {
public abstract double doSomthing(int num1, int num2);
}
2、实现对应的策略
public class AddStrategy extends Strategy{
@Override
public double doSomthing(int num1, int num2) {
return num1 + num2;
}
}
public class SubtractStrategy extends Strategy {
@Override
public double doSomthing(int num1, int num2) {
return num1 - num2;
}
}
public class MultiplyStrategy extends Strategy{
@Override
public double doSomthing(int num1, int num2) {
return num1 * num2;
}
}
public class DivisionStrategy extends Strategy {
@Override
public double doSomthing(int num1, int num2) {
return num1 / num2;
}
}
3、实现Context
public class Context {
private Strategy strategy;
public Context(Strategy strategy) {
this.strategy = strategy;
}
public double doSomthing(int num1, int num2) {
return strategy.doSomthing(num1, num2);
}
}
4、使用
public static void runStrategy(String type) {
Log.i(TAG, "策略模式");
int num1 = 10;
int num2 = 5;
//需要知道类型、对应的策略,和Context对象
StrategyType strategyType = StrategyType.getType(type);
Context context = null;
double result;
switch (strategyType) {
case ADD:
context = new Context(new AddStrategy());
result = context.doSomthing(num1, num2);
Log.i(TAG, "<-add->" + result);
break;
case SUB:
context = new Context(new SubtractStrategy());
result = context.doSomthing(num1, num2);
Log.i(TAG, "<-sub->" + result);
break;
default:
break;
}
}
至此,就完成了基本策略模式的运用,但是,从上面的例子可以看到,在策略选择的时候,还是得由客户端进行判断,然后才转给策略模式的Context
对象,在这种模式中,客户端需要知道的东西比较多,包括Context
对象,type类型、还有对应的策略,这本身没有减低客户端需要判断的压力,那有没有更好的实现呢?
简单工厂+策略模式
将策略模式和简单工厂模式进行结合,选择判断具体策略实现的职责也由Context
来承担,这样子就能够最大化减轻使用者的职责了。并且也仅仅需要知道ContextFactory
这个类即可。
public static double runFactoryStrategy(String type, int num1, int num2) {
StrategyType strategyType = StrategyType.getType(type);
Context context = null;
double result = 0;
switch (strategyType) {
case ADD:
context = new Context(new AddStrategy());
result = context.doSomthing(num1, num2);
Log.i(TAG, "<-add->" + result);
break;
case SUB:
context = new Context(new SubtractStrategy());
result = context.doSomthing(num1, num2);
Log.i(TAG, "<-sub->" + result);
break;
case MUL:
context = new Context(new MultiplyStrategy());
result = context.doSomthing(num1, num2);
Log.i(TAG, "<-mul->" + result);
break;
case DIV:
context = new Context(new DivisionStrategy());
result = context.doSomthing(num1, num2);
Log.i(TAG, "<-div->" + result);
break;
default:
break;
}
return result;
}
使用场景
- 1、如果有一系列的类,区别只是对应的实现不同,可以考虑使用这种模式;
- 2、过多的使用
if else
的场景,也可以考虑; - 3、有多种算法的情况下,需要选中其中某种获取结果(譬如做ABTest的时候)
网友评论