一、什么是策略模式?
- 策略模式定义:定义算法族分别封装起来,它们之间可以相互替换,此模式让算法的变化独立于使用算法的客户。
- 生活中的策略比如我们网上购物付款的时候:可以使用支付宝、微信、银联等等;这些都是为了实现同一个事儿的多种策略。
二、代码举例
- 上面说了网上购物付款的事儿,但是从用户角度说的;现在就从程序的角度来讲。
- 一个购物网站要接这些(支付宝、微信、银联)支付供用户选择,然后用户选择好后提交到后台。有的代码可能是这样写的:
//payMethod是前端传过来的
if("aliPay".equals(payMethod)){
//这里执行调用支付宝支付的逻辑
}else if("weChatPay".equals(payMethod)){
//这里执行调用微信支付的逻辑
}else if("unionPay".equals(payMethod)){
//这里执行调用银联支付的逻辑
}
- 这样写本身没错,但是并不建议这样写;试想下每次加一个支付方式这里又要加个if else,又要去动原来的代码了,在有多种算法相似的情况下,使用 if…else 会使代码复杂和难以维护。那么我们完全可以使用一个策略模式,定义一个抽像策略,然后把各个请求策略封装,客户想使用哪个就使用哪个,非常灵活和方便。策略模式和简单工厂很相似,确有不同,策略是一种行为模式,而简单工厂是创建型模式「创建对象」 。
- 下面就使用下策略模式去改造下这个支付:
- 首先定义一个支付接口,并定义一个都要的方法,所有的支付方式都实现他:
package com.zzq.test.model.strategy;
import java.util.Map;
public interface IPayMethod {
/**
* 创建订单
* @param params
* @return
*/
public String createOrder(Map<String,String> params);
}
package com.zzq.test.model.strategy;
import java.util.Map;
//支付宝
public class AliPay implements IPayMethod {
@Override
public String createOrder(Map<String, String> params) {
return null;
}
}
package com.zzq.test.model.strategy;
import java.util.Map;
//微信
public class WeChatPay implements IPayMethod{
@Override
public String createOrder(Map<String, String> params) {
// TODO Auto-generated method stub
return null;
}
}
package com.zzq.test.model.strategy;
import java.util.Map;
//银联
public class UnionPay implements IPayMethod{
@Override
public String createOrder(Map<String, String> params) {
// TODO Auto-generated method stub
return null;
}
}
package com.zzq.test.model.strategy;
import java.util.Map;
//切换支付方式的类
public class SwitchStrategy {
//持有一个支付方式
private IPayMethod payMethod;
//构造方法设置具体支付方式
public SwitchStrategy(IPayMethod payMethod) {
this.payMethod = payMethod;
}
//调用创建订单方法
public String createOrder(Map<String, String> params){
return payMethod.createOrder(params);
}
}
package com.zzq.test.model.strategy;
import java.util.HashMap;
import java.util.Map;
public class Client {
//实际应用中这块应该算是从数据库查或者读取的配置等等
public static Map<String,IPayMethod> payMethodMap = new HashMap<String, IPayMethod>();
static {
payMethodMap.put("aliPay", new AliPay());
payMethodMap.put("weChatPay", new WeChatPay());
payMethodMap.put("unionPay", new AliPay());
}
public static void main(String[] args) {
//payMethod 是前端传过来的
String payMethod = "aliPay";
IPayMethod iPayMethod = payMethodMap.get(payMethod);
SwitchStrategy ss = new SwitchStrategy(iPayMethod);
ss.createOrder(new HashMap<String, String>());
}
}
- 策略模式的优点: 减少了if else,并且符合类的单一原则和开闭原则,增加支付方式不用改现有代码(这点比较适用于聚合支付),修改某个支付方式也不会担心破坏了其他支付方式,代码耦合度更低了,更易扩展。
- 策略模式的缺点: 策略模式类会增多;所有策略类都需要对外暴露。