策略模式
1. 定义
定义一系列算法,把他们一个个封装起来,并且使他们可以互相替换。本模式使得算法
可以独立于使用它的客户而变化。
2. 策略模式的结构
- Strategy : 策略接口,用来约束一系列具体的策略算法。Context使用这个接口来调用具体的策略实现定义的算法
- ConcreteStrategy:具体的策略实现,也就是具体的算法实现。
- Context:上下文,负责和具体具体的策略类交互。
3. 本质
分离算法,选择实现
4. 实例
下面以订单支付支付为场景为例来演示策略模式:网上买东西订单支付一般会选择支付宝支付,微信支付,银联支付等等支付方式来实现。如果我们要实现这个功能其实很简单。下面给出不采用设计模式的实现:
Payment
/**
* 支付 的策略接口
* @author lijun
* @since 2018-03-16 13:48
*/
public interface Payment {
/**
* 支付接口
* @param userId 用户ID
* @param amount 支付金额
* @return PayState 支付状态
*/
PayState pay(String userId,double amount);
}
AliPay
/**
* 支付宝支付
* @author lijun
* @since 2018-03-16 13:57
*/
public class AliPay implements Payment {
/**
* 支付接口
*
* @param userId 用户ID
* @param amount 支付金额
* @return PayState 支付状态
*/
@Override
public PayState pay(String userId, double amount) {
System.out.println("欢迎使用支付宝");
System.out.println("查询账户余额,开始扣款");
return new PayState(200,"支付成功",amount);
}
}
WechatPay
/**
* 微信支付
* @author lijun
* @since 2018-03-16 14:02
*/
public class WechatPay implements Payment {
/**
* 支付接口
*
* @param userId 用户ID
* @param amount 支付金额
* @return PayState 支付状态
*/
@Override
public PayState pay(String userId, double amount) {
System.out.println("欢迎使用微信支付");
System.out.println("直接从微信红包扣款");
return new PayState(200,"支付成功",amount);
}
}
PayState
/**
* 支付状态
* @author lijun
* @since 2018-03-16 13:56
*/
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;
}
@Override
public String toString() {
return ("支付状态:[" + code + "]," + msg + ",交易详情:" + data);
}
}
OrderNoStrategy
/**
* OrderNoStrategy
*
* @author lijun
* @since 2018-03-16 14:24
*/
public class OrderNoStrategy {
/**
* 阿里支付
*/
private static final String ALI_PAY = "1";
private static final String WX_PAY = "1";
/**
* 支付
*
* @param userId 用户ID
* @param amount 支付金额
* @param orderType 支付类型
* @return
*/
PayState pay(String userId, double amount, String orderType) {
Payment payment = null;
if (ALI_PAY.equals(orderType)) {
payment = new AliPay();
} else if (WX_PAY.equals(orderType)) {
payment = new WechatPay();
} else {
payment = new AliPay();
}
return payment.pay(userId, amount);
}
}
调用:
@Test
public void payNoStrategy() throws Exception {
OrderNoStrategy order = new OrderNoStrategy();
PayState payState = order.pay("lijun", 200,"1");
System.out.println(payState);
}
输出:
欢迎使用支付宝
查询账户余额,开始扣款
支付状态:[200],支付成功,交易详情:200.0
功能是实现了,但是有什么缺点呢!上面只是实现了支付宝支付和微信支付,如果再添加银联卡支付OrderNoStrategy.pay() 得再加一个else if 如果支付渠道变的很多就会出现非常的多的if else if 。怎么消除这些if else 使用策略模式。 Payment 相当于(策略接口) AliPay(策略的实现) WechatPay(策略的实现) Order(上下文) 。
Order
/**
* 订单
*
* @author lijun
* @since 2018-03-16 14:03
*/
public class Order {
/**
* payment 支付接口
*/
private Payment payment;
public Order(Payment payment) {
this.payment = payment;
}
/**
* 上下文支付 和具体的策略类交互
*
* @param userId
* @param amount
* @return
*/
PayState pay(String userId, double amount) {
return payment.pay(userId, amount);
}
}
测试:
@Test
public void pay() throws Exception {
Order order = new Order(new AliPay());
PayState payState = order.pay("lijun", 200);
System.out.println(payState);
}
输出:
欢迎使用支付宝
查询账户余额,开始扣款
支付状态:[200],支付成功,交易详情:200.0
这样利用策略模式实现了支付,如果要再添加一种支付,变的非常简单只需要实现Payment 其他代码都不需要修改!客户端测试只需要传入新添加的支付的实现类即可。这样就消除了多个 if else。