工厂模式 + 策略模式 实战

104 阅读2分钟

一、前言

本案例实现根据code值可获取对应支付方式,外部直接调用支付方法进行业务流程,调用者无需关注每种支付方式的具体执行流程

二、代码实现

2.1 定义支付方式PayChannelEnum枚举类

定义getByCode(int code)根据code值获取枚举属性的方法

package com.ssm.user.designPattern.strategyPattern.demo;

public enum PayChannelEnum {
    ZFB_PAY(0, "支付宝支付"),
    WX_PAY(1, "微信支付"),
    BANK_PAY(2, "银行卡支付"),
    ;

    private int code;

    private String desc;

    PayChannelEnum(int code, String desc) {
        this.code = code;
        this.desc = desc;
    }

    /**
     * 根据code值获取支付渠道 枚举
     */
    public static PayChannelEnum getByCode(int codeVal) {
        for(PayChannelEnum payChannelEnum : PayChannelEnum.values()) {
            if(payChannelEnum.code == codeVal) {
                return payChannelEnum;
            }
        }
        return null;
    }

}

2.2 定义PayHandle支付方式模版类

public interface PayHandle { //定义支付模版

    PayChannelEnum getChannel(); //先获取支付方式

    void dealPay(); //再执行具体支付逻辑
}

2.3 定义支付类实现PayHandle模块定义自己的支付流程

银行卡支付

@Component
public class BankPayHandle implements PayHandle {
    @Override
    public PayChannelEnum getChannel() {
        return PayChannelEnum.BANK_PAY;
    }

    @Override
    public void dealPay() {
        System.out.println("银行卡支付");
    }
}

微信支付

@Component
public class WxPayHandle implements PayHandle {
    @Override
    public PayChannelEnum getChannel() {
        return PayChannelEnum.WX_PAY;
    }

    @Override
    public void dealPay() {
        System.out.println("微信支付");
    }
}

支付宝支付

@Component
public class ZfbPayHandle implements PayHandle {
    @Override
    public PayChannelEnum getChannel() {
        return PayChannelEnum.ZFB_PAY;
    }

    @Override
    public void dealPay() {
        System.out.println("支付宝支付");
    }
}

2.4 定义PayFactory支付工厂

目前我们可以根据PayChannelEnum的getByCode方法根据code值获取对应的枚举属性,但不知道枚举属性对应的是哪一个支付类。而我们想要的结果是:根据code值直接获取对应的支付类。所以需要定义Map映射<枚举属性,支付类>

@Component
public class PayFactory implements InitializingBean {
    @Resource //和@AutoWired一样都可获取接口的实现类(实现类也要加@Component注解)
    private List<PayHandle> payHandleList;

    private Map<PayChannelEnum, PayHandle> handleMap = new HashMap<>();

    public PayHandle getHandleByCode(int code) {
        PayChannelEnum payChannelEnum = PayChannelEnum.getByCode(code);
        return handleMap.get(payChannelEnum);
    }

    //凡是继承InitializingBean接口的类,在bean的属性初始化后都会执行该方法
    @Override
    public void afterPropertiesSet() throws Exception {
        for(PayHandle payHandle : payHandleList) {
            handleMap.put(payHandle.getChannel(), payHandle);
        }
    }
}

2.5 外部调用

@Component
public class PayHandleDemo {

    @Resource
    private PayFactory payFactory;

    public void dealPay(int code) {
        PayHandle payHandle = payFactory.getHandleByCode(code);
        payHandle.dealPay();
    }
}