策略模式
1.定義:
策略模式定義了一系列的算法,并將每一個(gè)算法封裝起來,而且使它們還可以相互替換。策略模式讓算法獨(dú)立于使用它的客戶端而獨(dú)立變化。
2.使用場(chǎng)景:
- 針對(duì)同一類型問題的多種處理方式,僅僅是具體行為有差別時(shí);
- 需要安全的封裝多種同一類型的操作時(shí);
- 出現(xiàn)同一抽象類有多個(gè)子類,而又需要使用else-if或者switch-case來具體選擇子類時(shí)。
3.UML圖

4.詳解:
策略模式將一系列的算法或策略抽象出一個(gè)統(tǒng)一的接口,不同的算法或策略有不同的實(shí)現(xiàn)類,這樣在客戶端就可以通過注入不同的實(shí)現(xiàn)對(duì)象來實(shí)現(xiàn)不同算法或策略的動(dòng)態(tài)替換,它可擴(kuò)展性、可維護(hù)性更高。它是一種行為型設(shè)計(jì)模式。
策略模式主要用來分離算法,在相同的行為抽象下有不同的具體實(shí)現(xiàn)策略,這也很好的演示了OCP原則。
- 優(yōu)點(diǎn):結(jié)構(gòu)清晰明了、使用簡(jiǎn)單直觀;降低耦合,擴(kuò)展方便;操作封裝更徹底,數(shù)據(jù)更安全;
- 缺點(diǎn):隨著策略的增加,子類會(huì)越來越多。
下面就以數(shù)學(xué)中的加減乘除舉例,使用兩種方案實(shí)現(xiàn),詳見下面代碼。
原始方案:
public static class Calculator {
private static final String ADD = "+";
private static final String SUBTRACT = "-";
private static final String MULTIPLY = "*";
private static final String DIVIDE = "/";
public static float calculate(float a, float b, String type) {
switch (type) {
case ADD:
return a + b;
case SUBTRACT:
return a - b;
case MULTIPLY:
return a * b;
case DIVIDE:
return a / b;
default:
return 0;
}
}
}
測(cè)試代碼:
public static void main(String[] args) {
//原始方案
System.out.println(Calculator.calculate(7, 5, Calculator.ADD));
System.out.println(Calculator.calculate(7, 5, Calculator.SUBTRACT));
System.out.println(Calculator.calculate(7, 5, Calculator.MULTIPLY));
System.out.println(Calculator.calculate(7, 5, Calculator.DIVIDE));
}
上面這種方案是很多程序猿會(huì)選擇的方案,因?yàn)橄鄬?duì)簡(jiǎn)單。但是如果隨著需求的增加,要取余/多次冪等操作,就要修改Calculator 類,并在其中加入case條件,這樣就違背了OCP原則。
策略模式修改后的方案
首先,上面的加減乘除四種方法,可以抽象出一個(gè)統(tǒng)一接口,如下:
public interface CalculateMethod {
float calculate(float a, float b);
}
接著就是具體的實(shí)現(xiàn)類:加減乘除
public static class Add implements CalculateMethod {
@Override
public float calculate(float a, float b) {
return a + b;
}
}
public static class Subtract implements CalculateMethod {
@Override
public float calculate(float a, float b) {
return a - b;
}
}
public static class Multiply implements CalculateMethod {
@Override
public float calculate(float a, float b) {
return a * b;
}
}
public static class Divide implements CalculateMethod {
@Override
public float calculate(float a, float b) {
return a / b;
}
}
然后就是最關(guān)鍵的策略模式修改后類了
public static class StrategyCalculator {
private CalculateMethod method;
public StrategyCalculator setStrategy(CalculateMethod method) {
this.method = method;
return this;
}
public float calculate(float a, float b) {
return method.calculate(a, b);
}
}
上面的代碼清晰明了,就是通過設(shè)置具體的策略,然后讓策略去執(zhí)行相應(yīng)的操作。是不是很簡(jiǎn)單?然后就是擴(kuò)展性很強(qiáng),如上所述,假如需要取余,僅添加一個(gè)類Mod實(shí)現(xiàn)CalculateMethod 接口即可,而不需修改已有的類。詳見代碼:
public static class Mod implements CalculateMethod {
@Override
public float calculate(float a, float b) {
return a % b;
}
}
測(cè)試代碼:
public static void main(String[] args) {
//策略模式修改方案
StrategyCalculator strategyCalculator = new StrategyCalculator();
System.out.println(strategyCalculator.setStrategy(new Add()).calculate(7, 5));//12.0
System.out.println(strategyCalculator.setStrategy(new Subtract()).calculate(7, 5));//2.0
System.out.println(strategyCalculator.setStrategy(new Multiply()).calculate(7, 5));//35.0
System.out.println(strategyCalculator.setStrategy(new Divide()).calculate(7, 5));//1.4
System.out.println(strategyCalculator.setStrategy(new Mod()).calculate(7, 5));//2.0
}