我对策略模式曾一度理解了,但实际使用上还是不够清晰,一次偶然的机会发现了这篇文章,看完之后对策略模式的组合使用理解更深了,于是我也分享给大家。
一、场景模拟
public void payment(String payType) {
if (payType.equals("ALI_PAY")) {
//支付宝支付
} else if (payType.equals("WECAHT_APY")) {
//微信支付
} else if (payType.equals("UNION_PAY")) {
//银联支付
} else if (payType.equals("JD_PAY")) {
//京东支付
} else {
//其它支付........
}
}
在支付场景中,随着业务的不断扩展,支付方式会越来越多,这样会堆叠大量的if-else判断逻辑,代码非常臃肿,耦合性非常高,并且这种if-else的编写破坏了设计模式六大原则中的里氏开闭原则(对扩展开放,修改关闭),不利于后续的变动和修改。为了使代码符合优雅的设计模式和编码形式,现在提供一种新的修改思路供大家参考,主要采用策略模式、工厂模式、单例模式去重构代码。
二、策略模式
/**
* 策略模式
*/
public abstract class PaymentStrategy {
public abstract String getName();
protected abstract double queryBalance(String uid);
public PayResult pay(String uid, double amount) {
if (queryBalance(uid) < amount) {
return new PayResult(500, "支付失败", "余额不足");
}
return new PayResult(200, "支付成功", "支付余额: " + (queryBalance(uid) - amount) + "元");
}
}
/**
* 支付宝支付策略
*/
public class AliPayStrategy extends PaymentStrategy {
@Override
public String getName() {
return "支付宝支付";
}
@Override
protected double queryBalance(String uid) {
return 200;
}
}
/**
* 微信支付策略
*/
public class WeChatPayStrategy extends PaymentStrategy {
@Override
public String getName() {
return "微信支付";
}
@Override
protected double queryBalance(String uid) {
return 300;
}
}
/**
* 银联支付策略
*/
public class UnionPayStrategy extends PaymentStrategy {
@Override
public String getName() {
return "银联支付";
}
@Override
protected double queryBalance(String uid) {
return 100;
}
}
/**
* 京东支付策略
*/
public class JDPayStrategy extends PaymentStrategy {
@Override
public String getName() {
return "京东支付";
}
@Override
protected double queryBalance(String uid) {
return 500;
}
}
三、支付方式枚举
/**
* 支付方式枚举
*/
public enum PaymentEnum {
ALI_PAY("ALI_PAY", new AliPayStrategy()),
WECHAT_PAY("WECHAT_PAY", new WeChatPayStrategy()),
UNION_PAY("UNION_PAY", new UnionPayStrategy()),
DEFAULT("DEFAULT", new JDPayStrategy());
private final String payName;
private final PaymentStrategy paymentStrategy;
PaymentEnum(String payName, PaymentStrategy paymentStrategy) {
this.payName = payName;
this.paymentStrategy = paymentStrategy;
}
public String getPayName() {
return payName;
}
public PaymentStrategy getPaymentStrategy() {
return paymentStrategy;
}
}
四、工厂模式+单例模式
/**
* 支付方式工厂类
*/
public class PaymentFactory {
private static Map<String, PaymentStrategy> register = new HashMap<>();
static {
for (PaymentEnum p : PaymentEnum.values()) {
register.put(p.getPayName(), p.getPaymentStrategy());
}
}
/**
* 单例+饿汉(注册表)
*/
public static PaymentStrategy getInstance(String payType) {
if (register.containsKey(payType)) {
return register.get(payType);
}
return PaymentEnum.DEFAULT.getPaymentStrategy();
}
}
五、业务类
public class PayResult {
private int code;
private Object data;
private String msg;
public PayResult(int code, Object data, String msg) {
this.code = code;
this.data = data;
this.msg = msg;
}
public int getCode() {
return code;
}
public void setCode(int code) {
this.code = code;
}
public Object getData() {
return data;
}
public void setData(Object data) {
this.data = data;
}
public String getMsg() {
return msg;
}
public void setMsg(String msg) {
this.msg = msg;
}
@Override
public String toString() {
return "PayResult{" +
"code=" + code +
", data=" + data +
", msg='" + msg + '\'' +
'}';
}
/**
* 订单类
*/
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 String getUid() {
return uid;
}
public void setUid(String uid) {
this.uid = uid;
}
public String getOrderId() {
return orderId;
}
public void setOrderId(String orderId) {
this.orderId = orderId;
}
public Double getAmount() {
return amount;
}
public void setAmount(Double amount) {
this.amount = amount;
}
public PayResult pay(String payType) {
PaymentStrategy paymentStrategy = PaymentFactory.getInstance(payType);
System.out.println("欢迎使用" + paymentStrategy.getName());
System.out.println("本次交易金额为:" + amount + "元, 开始扣款...");
return paymentStrategy.pay(uid,amount);
}
}
六、测试
public class PayTest {
public static void main(String[] args) {
Order order = new Order("6", "6", 50.0);
PayResult msg = order.pay(PaymentEnum.ALI_PAY.getPayName());
System.out.println(msg.toString());
}
}
欢迎使用支付宝支付
本次交易金额为:50.0元, 开始扣款...
PayResult{code=200, data=支付成功, msg='支付余额: 150.0'}
作者:爪哇驿站
链接:https://www.jianshu.com/p/d6d44db4ce65
来源:简书