政策模式
政策模式定義
Define a familly algorithms, encapsulate each one, and make them interchangeable.(定義一組算法,将每個算法都封裝起來,并且使他們之間互相轉換)。
從以上官方定義分析到政策模式具有三個角色分别是:
- 封裝角色
- 抽象政策角色(政策接口)
- 具體政策角色(實作政策接口的類)
政策模式實作電腦
我們分析一下電腦的簡單運算,以加減法為例來劃分一下其中的角色,比如 加法:1+1=2,減法1-1=0。這裡加法和減法都是一個運算可以了解為兩個政策;他們都有計算的功能需要定義一個接口提供統一的運算方法,這個為抽象政策角色;高層實作減價法則為封裝角色及将接口放進去,通過接口調用,是以高層不用知道具體是加法還是減法。
是以封裝角色起到了承上啟下的作用,屏蔽了高層子產品對政策、算法的直接通路,封裝可能存在的變化。
下來簡單實作電腦加減法的功能:
政策的接口,定義執行的方法:
package design.strategy.c001;
/**
* 定義政策接口(一組政策)
* @author yanwenfei
*
*/
public interface IStrategy {
//政策需要執行的方法
public int exec(int a, int b);
}
建立具體的政策角色及加法和減法
package design.strategy.c001;
/**
* 政策A加法
* @author yanwenfei
*
*/
public class StrategyADD implements IStrategy {
@Override
public int exec(int a, int b) {
return a+b;
}
}
package design.strategy.c001;
/**
* 減法政策
* @author yanwenfei
*
*/
public class StrategySub implements IStrategy {
@Override
public int exec(int a, int b) {
return a - b;
}
}
封裝角色。這裡通過構造方法将具體的政策傳入高層,而高層不用知道具體是哪種政策,隻需要調用抽象政策的方法即可
package design.strategy.c001;
/**
* 政策分裝類
* @author yanwenfei
*/
public class Calculator {
private IStrategy strategy;
//切換政策
public Calculator(IStrategy strategy) {
this.strategy = strategy;
}
//執行政策方法
public int exec(int a, int b){
return strategy.exec(a, b);
}
}
場景類
package design.strategy.c001;
public class TestMain {
public static void main(String[] args) {
Calculator calculator = null;
IStrategy streadd = new StrategyADD();//建立加法政策;
calculator = new Calculator(streadd);//切換政策
int add = calculator.exec(20, 30);
System.out.println("20 + 30 = " + add);
IStrategy stresub = new StrategySub();//建立減法政策;
calculator = new Calculator(stresub);//切換政策
int sub = calculator.exec(20, 30);
System.out.println("20 - 30 = " + sub);
}
}
運算結果:
10 + 30 = 40
10 - 30 = -20
以上為政策模式傳統的實作方式,肯定很多人能看出來這個政策模式有很多缺點,雖然便于擴充,但是每一個政策都是一個類,這個先不說,下來看一下很牛逼的政策枚舉。
政策枚舉
我們可以使用枚舉在一個類中實作以上所有的功能及三種不同的角色,對不熟悉枚舉的小夥伴可以查閱資料,下來看看通過枚舉實作政策模式
package design.strategy.c002;
/**
* 政策枚舉
* @author yanwenfei
*/
public enum Calculator {
ADD("+") {
@Override
public int exec(int a, int b) {
// TODO Auto-generated method stub
return a+b;
}
},
SUB("-") {
@Override
public int exec(int a, int b) {
// TODO Auto-generated method stub
return a-b;
}
};
public abstract int exec(int a, int b);
//運算符
private String value = "";
private Calculator(String value) {
this.value = value;
}
public String getValue() {
return value;
}
}
場景類:
package design.strategy.c002;
public class TestMain {
public static void main(String[] args) {
int add = Calculator.ADD.exec(10, 30);
System.out.println("10 + 30 = "+add);
int sub = Calculator.SUB.exec(10, 30);
System.out.println("10 - 30 = "+sub);
}
}
運算結果:
10 + 30 = 40
10 - 30 = -20
這裡已經結束了,感覺是不是很爽,簡直太爽了,通過枚舉的使用,在一個類中就完美的實作了政策模式
在枚舉類中,定義的抽象方法就像當時之前的接口,每一個枚舉ADD SUB相當是一個具體的實作類(政策角色),而整個枚舉類就是政策的分裝角色。
政策模式優點
- 算法可以自由切換(高層屏蔽算法,角色自由切換)
- 避免使用多重條件判斷(如果算法過多就會出現很多種相同的判斷,很難維護)
- 擴充性好(可自由添加取消算法 而不影響整個功能)
政策模式缺點
- 政策類數量增多(每一個政策類複用性很小,如果需要增加算法,就隻能新增類)
- 所有的政策類都需要對外暴露(使用的人必須了解使用政策,這個就需要其它模式來補充,比如工廠模式、代理模式)