策略模式封装了变化!!!
策略模式是一种定义一系列算法的方法,从概念上来看,所有这些算法完成相同的工作,只是实现不同,它可以以相同的方式调用所有的算法,减少了各种算法与使用之间耦合。
说得直白一点也就是将实现同一个功能的不同算法封装在一起,客户端不需要关心算法的实现,并且通过简单的代码调用即可。
在实际的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);
}
}
策略模式的优点是简化了单元测试,每种算法都有自己的类,可以单独测试。也很利于扩展,添加一种支付方式的话,只需要添加一个算法类,客户端直接调用就行,不需要做任何修改。