策略模式
策略模式定義了算法家族,分別封裝起來,讓他們之間可以互相轉(zhuǎn)換,這個模式的算法變化,不會影響到使用算法的客戶。
結(jié)構(gòu)圖
其中,Context對象以聚合的方式,擁有Strategy對象。
-w790
代碼實現(xiàn)
1、創(chuàng)建基類或者接口
public abstract class Strategy {
public abstract double doSomthing(int num1, int num2);
}
2、實現(xiàn)對應(yīng)的策略
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、實現(xiàn)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;
//需要知道類型、對應(yīng)的策略,和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;
}
}
至此,就完成了基本策略模式的運用,但是,從上面的例子可以看到,在策略選擇的時候,還是得由客戶端進行判斷,然后才轉(zhuǎn)給策略模式的Context對象,在這種模式中,客戶端需要知道的東西比較多,包括Context對象,type類型、還有對應(yīng)的策略,這本身沒有減低客戶端需要判斷的壓力,那有沒有更好的實現(xiàn)呢?
簡單工廠+策略模式
將策略模式和簡單工廠模式進行結(jié)合,選擇判斷具體策略實現(xiàn)的職責也由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、如果有一系列的類,區(qū)別只是對應(yīng)的實現(xiàn)不同,可以考慮使用這種模式;
- 2、過多的使用
if else的場景,也可以考慮; - 3、有多種算法的情況下,需要選中其中某種獲取結(jié)果(譬如做ABTest的時候)
