支付场景中利用 策略模式+工厂模式+单例模式 解决if else过多的问题

一、场景模拟
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 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'}

你可能感兴趣的:(支付场景中利用 策略模式+工厂模式+单例模式 解决if else过多的问题)