策略模式封裝了變化!!!
策略模式是一種定義一系列算法的方法,從概念上來看,所有這些算法完成相同的工作,只是實現不同,它可以以相同的方式調用所有的算法,減少了各種算法與使用之間耦合。
說得直白一點也就是將實現同一個功能的不同算法封裝在一起,客戶端不需要關心算法的實現,并且通過簡單的代碼調用即可。
在實際的App項目中,支付功能就可以通過此模式來進行封裝。支付的方式有很多種,比如微信支付、支付寶支付、銀聯支付...每種支付方式內部的實現都不相同,但是都是為了完成支付功能。每一種算法都可以認為是一種策略,每種策略都是為了完成支付這個功能,因此正好符合策略模式的主旨。
下面通過簡單的代碼來實現App支付功能:
- 支付接口(策略接口,定義所有支持的算法的公共方法):
public interface AppPay {
void pay(float money);
}
微信支付(策略一):
public class WeChatPay implements AppPay {
@Override
public void pay(float money) {
System.out.println("這是微信支付,支付的金額為:" + money);
}
}支付寶支付(策略二):
public class AliPay implements AppPay {
@Override
public void pay(float money) {
System.out.println("這是支付寶支付,支付金額為:" + money);
}
}銀聯支付(策略三):
public class UnionPay implements AppPay {
@Override
public void pay(float money) {
System.out.println("這是銀聯支付,支付金額為:" + money);
}
}配置一個Context上下文來維護AppPay對象的引用:
public class AppPayContext {
private AppPay appPay;
public AppPayContext(AppPay appPay) {
this.appPay = appPay;
}
public void pay(float money) {
this.appPay.pay(money);
}
}客戶端調用代碼:
public class Client {
public static void main(String[] args) throws Exception {
AppPayContext context = null;
int payType = new Random().nextInt(100);
switch (payType % 3) {
case 1:
context = new AppPayContext(new WeChatPay());
break;
case 2:
context = new AppPayContext(new AliPay());
break;
case 3:
context = new AppPayContext(new UnionPay());
break;
}
if (context != null) {
context.pay(100);
}
}
}
從客戶端代碼上可以看到,客戶端不需要關心各種支付算法的具體實現,僅僅通過策略上下文進行間接調用即可。
以上代碼就是策略模式的簡單實現,為了簡化客戶端的調用代碼,可以結合抽象工廠以及反射來實現,代碼如下:
AppPayContext:
public class AppPayContext {
public static void pay(Class clazz, float money) throws Exception {
AppPay appPay = (AppPay) clazz.newInstance();
appPay.pay(money);
}
}客戶端調用代碼:
public class Client {
public static void main(String[] args) throws Exception {
AppPayContext.pay(WeChat.class, 4000);
//AppPayContext.pay(AliPay.class, 4000);
//AppPayContext.pay(UnionPay.class, 4000);
}
}
策略模式的優點是簡化了單元測試,每種算法都有自己的類,可以單獨測試。也很利于擴展,添加一種支付方式的話,只需要添加一個算法類,客戶端直接調用就行,不需要做任何修改。