策略模式(Strategy):在设计模式中属于一种行为模式,一般来说一个类的行为在使用算法可以更改,或者使用的service服务方法有多种选择的时候可以是用策略模式。
中在实例化对象的时候用到 Strategy 模式,在 SimpleInstantiationStrategy 有使用。
使用场景
一个是当有固定算法封装时候,在根据用户需求处理数据的时候需要对算法进行选择的时候可以用到;另一种就是常见的在支付系统中对多种支付方式的选择可以使用到策略模式。
使用优缺点
优点:
1.算法和服务可以只有切换
2.避免多重条件判断
3.扩展性良好
缺点:
策略类会增多,所有策略类需要对外暴露。
举例实现
下面就以一个简略的订单支付系统中选择支付方式来实现策略模式。在实际订单支付中,经常有多种支付方式选择:支付宝(AliPay),微信(WeChatPay),银联(UnionPay),京东白条(JDPay),那么就可以使用一个类来管理和选择这些支付方式。
类图:
一个Payment接口,里面一个pay方法,传入用户id和金额。
package Strategy.pay.payport;
import Strategy.pay.PayState;
public interface Payment {
public PayState pay(String uid, double amount);
}
然后是四个实际支付服务实现接口Payment
AliPay
package Strategy.pay.payport;
import Strategy.pay.PayState;
public class AliPay implements Payment {
@Override
public PayState pay(String uid, double amount) {
System.out.println("欢迎使用支付宝");
System.out.println("查询账户余额,开始扣款");
return new PayState(200,"支付成功",amount);
}
}
JDPay
package Strategy.pay.payport;
import Strategy.pay.PayState;
public class JDPay implements Payment {
@Override
public PayState pay(String uid, double amount) {
System.out.println("欢迎使用京东白条");
System.out.println("查询账户余额,开始扣款");
return new PayState(200,"支付成功",amount);
}
}
WeChatPay
package Strategy.pay.payport;
import Strategy.pay.PayState;
public class WeChatPay implements Payment {
@Override
public PayState pay(String uid, double amount) {
System.out.println("欢迎使用微信支付");
System.out.println("直接从微信红包扣款");
return new PayState(200,"支付成功",amount);
}
}
UnionPay
package Strategy.pay.payport;
import Strategy.pay.PayState;
public class UnionPay implements Payment {
@Override
public PayState pay(String uid, double amount) {
System.out.println("欢迎使用银联卡支付");
System.out.println("查询账户余额,开始扣款");
return new PayState(200,"支付成功",amount);
}
}
然后一个枚举类型来管理选择四种支付方式:
枚举类PayType:
package Strategy.pay.payport;
import Strategy.pay.PayState;
public enum PayType {
ALI_PAY(new AliPay()),
WECHAT_PAY(new WeChatPay()),
UNION_PAY(new UnionPay()),
JD_PAY(new JDPay());
private Payment payment;
PayType(Payment payment){
this.payment = payment;
}
public Payment get(){ return this.payment;}
}
然后一个简略的订单类,里面主要是下订单和支付方法
package Strategy.pay;
import Strategy.pay.payport.PayType;
public class Order {
private String uid;
private String orderId;
private double amount;
public Order(String uid,String orderId,double amount){
this.uid = uid;
this.orderId = orderId;
this.amount = amount;
}
public PayState pay(PayType payType){
return payType.get().pay(this.uid,this.amount);
}
}
在就是显示支付状态类:
package Strategy.pay;
public class PayState {
private int code;
private Object data;
private String msg;
public PayState(int code, String msg,Object data) {
this.code = code;
this.data = data;
this.msg = msg;
}
public String toString(){
return ("支付状态:[" + code + "]," + msg + ",交易详情:" + data);
}
}
然后是测试类
package Strategy.pay;
import Strategy.pay.payport.PayType;
public class StrategyTest {
public static void main(String[] args) {
//省略把商品添加到购物车,再从购物车下单
//直接从点单开始
Order order = new Order("1","20181200001000009",324.45);
//开始支付,选择微信支付、支付宝、银联卡、京东白条、财付通
//每个渠道它支付的具体算法是不一样的
//基本算法固定的
//这个值是在支付的时候才决定用哪个值
System.out.println(order.pay(PayType.WECHAT_PAY));
}
}
执行结果:
这就是一个简略的支付选择方案使用策略模式实现的方式,当然实际的执行中会复杂很多。使用策略模式的优势就在于,当增加新的支付方式的时候,代码扩展性很好,需要调整的结构减少很多。