定义:策略模式定义了一系列的算法,并将每一个算法封装起来,而且使他们可以相互替换,让算法独立于使用它的客户而独立变化。
分析下定义,策略模式定义和封装了一系列的算法,它们是可以相互替换的,也就是说它们具有共性,而它们的共性就体现在策略接口的行为上,另外为了达到最后一句话的目的,也就是说让算法独立于使用它的客户而独立变化,我们需要让客户端依赖于策略接口。
package com.gupaoedu.strategy;
/**
* ClassName:Order
* PackageName:com.gupaoedu.strategy
* Description:
*订单类
* @date:2020/7/18 21:34
* @author:robin
*/
public class Order {
//用户id
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(PayChannels onePay){
//完美解决了switch 的过程,不需要在代码逻辑中写switch 了
//更不需要写if /else了
public PayState pay(PayType payType){
//调用支付渠道,返回支付状态
// return onePay.payChannels(uid,amount);
return payType.get().payChannels(uid,amount);
}
}
package com.gupaoedu.strategy;
/**
* ClassName:payChannels
* PackageName:com.gupaoedu.strategy
* Description:
*支付渠道
* @date:2020/7/18 21:39
* @author:robin
*/
public interface PayChannels {
//缺点:每次增加一个渠道,就维护接口一次,违背了开闭原则 ,所以把它干掉
// final PayChannels ALI_PAY=new AliPay();
// final PayChannels UNION_PAY=new UnionPay();
// final PayChannels WECHAT_PAY=new WechatPay();
//传入用户编号,用户金额,必然返回支付状态
PayState payChannels(String uid,double amount);
}
package com.gupaoedu.strategy;
/**
* ClassName:AliPay
* PackageName:com.gupaoedu.strategy
* Description:
*
* @date:2020/7/18 21:59
* @author:13812536906
*/
public class AliPay implements PayChannels {
@Override
public PayState payChannels(String uid, double amount) {
System.out.println("欢迎使用支付宝支付");
System.out.println("查询账户余额开始扣款");
return new PayState(200,amount,"支付成功");
}
}
package com.gupaoedu.strategy;
/**
* ClassName:UnionPay
* PackageName:com.gupaoedu.strategy
* Description:
*
* @date:2020/7/18 22:06
* @author:robin
*/
public class UnionPay implements PayChannels {
@Override
public PayState payChannels(String uid, double amount) {
System.out.println("欢迎使用银联支付");
System.out.println("查询账户余额开始扣款");
return new PayState(200,amount,"支付成功");
}
}
package com.gupaoedu.strategy;
/**
* ClassName:WechatPay
* PackageName:com.gupaoedu.strategy
* Description:
*
* @date:2020/7/18 22:05
* @author:robin
*/
public class WechatPay implements PayChannels {
@Override
public PayState payChannels(String uid, double amount) {
System.out.println("欢迎使用微信支付");
System.out.println("查询账户余额开始扣款");
return new PayState(200,amount,"支付成功");
}
}
package com.gupaoedu.strategy;
/**
* ClassName:PayState
* PackageName:com.gupaoedu.strategy
* Description:
*支付状态
* @date:2020/7/18 21:40
* @author:robin
*/
public class PayState {
//返回代码,成功与否, 200成功(一般表示通信成功)
private int code;
//返回数据,交易详情
private Object data;
//返回状态信息(比如缺少参数信息)
private String msg;
public PayState(int code, Object data, String msg) {
this.code = code;
this.data = data;
this.msg = msg;
}
@Override
public String toString() {
return "支付状态【" +
"code=" + code +
", 交易详情=" + data +
", msg='" + msg + '\'' +
'】';
}
}
package com.gupaoedu.strategy;
/**
* ClassName:PayType
* PackageName:com.gupaoedu.strategy
* Description:
*支付类型:
* 枚举,姑且就是一个常量池
* @date:2020/7/18 22:20
* @author:robin
*/
public enum PayType {
ALI_PAY(new AliPay()),WECHAT_PAY(new WechatPay()),UNION_PAY(new UnionPay());
private PayChannels payChannels;
PayType(PayChannels payChannels) {
this.payChannels = payChannels;
}
//
public PayChannels get(){
return this.payChannels;
}
}
package com.gupaoedu.strategy;
/**
* ClassName:PayStrategyTest
* PackageName:com.gupaoedu.strategy
* Description:
*
* @date:2020/7/18 21:55
* @author:robin
*/
public class PayStrategyTest {
public static void main(String[] args) {
//省略把商品添加到购物车,再从购物车下单
//直接从订单开始
Order order = new Order("1","11111111",23.34);
//开始支付,微信、支付宝、银联
//每个渠道支付的算法是不一样的,基本都是固定的,我们客户有选择权去选择某一种算法去支付。
// PayState payState = order.pay(new AliPay());
//第一个版本:
// PayState payState = order.pay(new WechatPay());
//第二个版本: 不需要 new 了,直接 .调用 ----->缺点:每次增加一个渠道,就维护接口一次,违背了开闭原则
// PayState payState = order.pay(PayChannels.ALI_PAY);
//第三个版本(完美终结版),直接点就可以了,相当于前端的选项卡。每次增加支付渠道的时候直接在枚举中加常量就可以了。
// PayState payState = order.pay(PayType.WECHAT_PAY);
/**
* 返回结果:
* 欢迎使用银联支付
* 查询账户余额开始扣款
* 支付状态【code=200, 交易详情=23.34, msg='支付成功'】
*/
//PayType.UNION_PAY这个值是用户在支付的时候才决定用哪个值
//现在我们已经 **预先** 定义好了用户用哪个支付渠道,我们就new哪个。
PayState payState = order.pay(PayType.UNION_PAY);
//如何调用实际的算法
System.out.println(payState);
}
}