java策略模式解决支付问题,消除if、else,代码可运行

本来打算1024发搞个徽章,结果记错时间了(。•́︿•̀。)

1.业务场景

支付方式有支付宝支付、微信支付、网银支付等等,如果在代码中通过不断的写if-elseif去实现的话,虽然看起来更直观,但实际上不利于后续的扩展和维护,后期如果由于业务需要使用混合支付的话,就需要改动if-elseif的逻辑,违反了开闭原则,代码如下:

String payTypeCode = "WX";
if ("WX".equals(payTypeCode)){
    System.out.println("微信支付");
}else if ("ALI".equals(payTypeCode)){
    System.out.println("支付宝支付");
}else if ("WANGYIN".equals(payTypeCode)){
    System.out.println("网银支付");
}else {
    System.out.println("混合支付支付");
}

2.解决方案

通过工厂模式+策略模式+自定义注解的方式彻底消除if-elseif,提高代码的可扩展性,最终达到实现开闭原则的目的

3.代码设计

3.1首先建立如下的包目录结构

pay
    annotation          //支付方式自定义注解
    enums               //支付方式枚举类
    service             //支付服务接口
        strategy        //支付服务接口的策略实现类

3.2在enums包下新建支付方式的注解,代码如下

@Getter
public enum PayTypeEnum {
    /**
     * 微信支付
     */
    WX("WX","微信支付"),

    /**
     * 支付宝支付
     */
    ALI("ALI","支付宝");

    /**
     * 支付方式内部编码
     */
    private String code;

    /**
     * 支付方式名称
     */
    private String info;

    /**
     * 构造方法
     * @param code 支付方式内部编码
     * @param info 支付方式名称
     */
    PayTypeEnum(String code, String info) {
        this.code = code;
        this.info = info;
    }

    /**
     * 根据code获取枚举
     * @param code 支付方式内部编码
     * @return 支付方式
     */
    public static PayTypeEnum getValue(String code) {
        for (PayTypeEnum payType : values()) {
            if (payType.code.equals(code)) {
                return payType;
            }
        }
        return null;
    }
}

3.3 annotation包下新建支付方式的注解,代码如下

@Target({ElementType.TYPE})
@Retention(RetentionPolicy.RUNTIME)
@Documented
public @interface PayType {

    /**
     * 支付方式的值为PayTypeEnum枚举
     * @return
     */
    PayTypeEnum value();
}

3.4 service包下新建支付服务接口,代码如下

public interface PayService {

    /**
     * 支付
     */
    void pay();
}

3.5 strategy包下新建支付服务的策略实现类

3.5.1 支付宝支付策略类:

@PayType(value = PayTypeEnum.ALI)
@Service
public class AliPayServiceStrategy implements PayService {
    /**
     * 支付
     */
    @Override
    public void pay() {
        System.out.println("支付宝支付成功");
    }
}

3.5.2微信支付策略类

@PayType(value = PayTypeEnum.WX)
@Service
public class WxPayServiceStrategy implements PayService {
    /**
     * 支付
     */
    @Override
    public void pay() {
        System.out.println("微信支付成功");
    }
}

3.6 pay包下新建支付服务策略工厂

@Component
public class PayServiceFactory implements ApplicationContextAware {

    /**
     * 支付方式枚举-支付服务的映射集合
     */
    private static final Map<PayTypeEnum, PayService> payServiceMapping = new HashMap<>();

    /**
     * 工厂方法获取支付服务实现
     *
     * @param payTypeCode 支付方式的内部编码
     * @return 支付服务
     */
    public static final PayService getPayService(String payTypeCode) {
        PayTypeEnum payTypeEnum = PayTypeEnum.getValue(payTypeCode);
        if (payTypeEnum == null) {
            throw BusinessException.build("无效的支付编码");
        }
        PayService payService = payServiceMapping.get(payTypeEnum);
        if (payService == null) {
            throw BusinessException.build("没有匹配的支付服务实现类");
        }
        return payService;
    }

    /**
     * 初始化支付枚举-支付服务的映射
     * @param applicationContext
     * @throws BeansException
     */
    @Override
    public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
        Map<String, Object> payServiceMap = applicationContext.getBeansWithAnnotation(PayType.class);
        if (CollectionUtils.isEmpty(payServiceMap)) {
            throw BusinessException.build("支付服务映射初始化失败");
        }
        payServiceMap.forEach((key,bean) -> {
            if (!(bean instanceof PayService)) {
                throw BusinessException.build("注解:" + PayType.class + ",只能用于" + PayService.class + "的实现类中");
            }
            PayService payService = (PayService)bean;
            PayType annotation = payService.getClass().getAnnotation(PayType.class);
            payServiceMapping.put(annotation.value(),payService);
        });
    }

}

3.7代码中调用

 /**
     * 根据前端选择的支付方式进行支付
     *
     * @param payTypeCode 支付方式内部编码code
     */
    @GetMapping("/pay")
    public void pay(String payTypeCode) {

        //根据支付编码获取支付服务
        PayService payService = PayServiceFactory.getPayService(payTypeCode);

        //实际的支付业务操作
        payService.pay();

    }

通过传入的支付方式编码,输出不同的内容 微信支付成功 或者 支付宝支付成功

  • 5
    点赞
  • 19
    收藏
    觉得还不错? 一键收藏
  • 3
    评论
Java策略模式可以通过消除if-else语句来实现。使用策略模式可以将不同的策略封装为不同的策略类,并通过一个策略接口来统一调用这些策略。在Java中,可以定义一个策略接口,该接口包含一个执行策略的方法。 然后,可以创建一个策略上下文类,该类包含一个策略对象,并通过构造函数将具体的策略传入。策略上下文类中包含一个执行策略的方法,该方法调用策略对象的执行方法。这样,客户端只需要创建一个策略上下文对象,并调用其执行策略的方法即可,而不需要使用if-else语句来判断使用哪种策略。 这样的设计可以提高代码的可维护性和可扩展性,当需要新增或修改策略时,只需要新增或修改相应的策略类和策略上下文类,而不需要修改客户端代码。这符合开闭原则,能够使代码灵活和易于维护。<span class="em">1</span><span class="em">2</span><span class="em">3</span> #### 引用[.reference_title] - *1* *2* *3* [Java中使用工厂模式和策略模式优雅消除if-else语句(UML类图+案例分析)](https://blog.csdn.net/HJW_233/article/details/131661714)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v93^chatsearchT3_1"}}] [.reference_item style="max-width: 100%"] [ .reference_list ]
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值