常用设计模式——策略模式
常用设计模式——策略模式
定义:定义一组算法,将每个算法都封装起来,并且使他们之间可以互换
案例分析:
想必大家基本都写过支付接口,一般呢,自己的平台都有好几种支付方式,比如:支付宝、微信、银行卡等。那么当在选择支付方式的时候,是通过if else判断来决定用哪一种还是另外的方式呢?如果是if else的话这种方式就是判断太多,容易混淆并且也不易于维护,那么今天我们就以策略模式的方式来解决这个问题。
既然需要算法,那么我们就来定义一组算法,想一想,支付的算法是什么,当时就是判断余额,进行支付(当然真实环境中还有支付通知等)
按照这样的逻辑我们先定义一个支付抽象类:
public abstract class Pay {
//支付名称
public abstract String getName();
//获取余额
public abstract BigDecimal getBlance(String uid);
/**
* 支付
* @param money
*/
public Result pay(String uid,BigDecimal money){
if (getBlance(uid).compareTo(money) >=0 ){
return new Result(200,getName()+"支付成功","支付金额:"+money);
}
return new Result(500,"支付失败","余额不足");
}
}
然后再定义两种支付方式:
- 支付宝支付
public class AliPay extends Pay {
public String getName() {
return "支付宝支付";
}
public BigDecimal getBlance(String uid) {
return new BigDecimal(20);
}
}
2.微信支付
public class WeChatPay extends Pay {
public String getName() {
return "微信支付";
}
public BigDecimal getBlance(String uid) {
return new BigDecimal(15);
}
}
那么有了支付方式我们就可以支付了,真的是这样吗?如果就这样 到头来我们还是需要if else 判断,问题根本没有解决,那怎么来办呢?
支付算法有了,但是我们怎么来选择呢?这时我们需要将所有的支付方式都提供出来,需要用的时候供我们选择就好了,
那么重点来了,定义支付方式获取策略:其实就是获取支付方式实例
public class PayStrategy {
//所有支付
private static final Map<String,Pay> pay = new HashMap<String, Pay>();
public static String AliPay = "AliPay";
public static String WhChat = "WhChat";
public static String Default = AliPay;
/**
* 静态块加载支付方式
*/
static {
pay.put(AliPay,new AliPay());
pay.put(WhChat,new WeChatPay());
}
/**
* 获取支付
* @param key
* @return
*/
public Pay getPay(String key ){
if (!pay.containsKey(key)){
return pay.get(Default);
}
return pay.get(key);
}
}
支付策略搞定,我们来测试一下:
public class PayTest {
public static void main(String[] args) {
//省略下单流程 直接支付
PayStrategy payStrategy = new PayStrategy();
Pay pay = payStrategy.getPay(PayStrategy.WhChat);
Result result = pay.pay("1", new BigDecimal(12));
System.out.println(result);
}
}
运行结果如下(记得toString):
Result{支付状态:200, 支付详情:微信支付支付成功 支付金额:12}
这里有个缺点,就是我们需要知道一共有哪些支付方式,也就是有哪些支付策略,这是我们需要提前了解的。
当然这里是web开发的话,我们可以将支付策略提供到页面,让用户选择心仪的支付方式(单选)。
如果这样做是不是好了很多,避免了多重判断,如果新增一种支付方式,扩展也很方便。但美中不足的就是需要提前了解有哪些策略(可以其他设计模式解决,如工厂模式),二呢类的数目增多了,相对于好处呢,这点缺点就不算什么了。
最后看一下类图:
idea中查看类图快捷键:ctr + alt + shift + u
更多使用场景:
- 多个类只有在算法上略有不同
- 算法需要自由切换
- 需要屏幕算法规则
我们都可以使用策略模式来对应解决。