Spring项目中使用策略模式和工厂模式

不同类型的数据对应不同的处理的情况,自己经常以下边的方式处理,个人感觉扩展性也比较强,做个记录。
下边以多种支付类型做示例
假如当前系统支持微信支付和支付宝支付
文章来自我的个人博客:Pei’s Blog

示例

  1. 定义支付类型枚举,方便统一管理

    public enum PayEnum {
    
        /**
         * 微信支付
         */
        WX(1, "wx"),
    
        /**
         * 支付宝支付
         */
        ALIPAY(2, "alipay");
    
        private final int code;
        private final String en;
    
        PayEnum(int code, String en) {
            this.code = code;
            this.en = en;
        }
    
        public int getCode() {
            return code;
        }
    
        public String getEn() {
            return en;
        }
    
        /**
         * 方便通过code来获取枚举类型
         *
         * @param code
         * @return
         */
        public static PayEnum getByCode(int code) {
            for (PayEnum value : values()) {
                if (value.getCode() == code) {
                    return value;
                }
            }
            return null;
        }
    }
    
  2. 定义一个支付处理类PayService

    /**
     * PayService
     *
     * @author ZXP
     * @date 2021/12/4 21:23
     */
    public interface PayService {
    
        /**
         * 支持的支付类型
         *
         * @return
         */
        PayEnum getPayType();
    
        /**
         * 具体的支付逻辑
         *
         * @param obj
         */
        void pay(Object obj);
    }
    
  3. 两个实现类WxPayServiceImplAliPayServiceImpl,分别对应处理微信支付和支付宝支付,别忘了加**@Service**注解(@Component也一样)

    /**
     * 微信支付处理类
     *
     * @author ZXP
     * @date 2021/12/4 21:28
     */
    @Service
    public class WxPayServiceImpl implements PayService {
    
        @Override
        public PayEnum getPayType() {
            return PayEnum.WX;
        }
    
        @Override
        public void pay(Object obj) {
            // wx支付逻辑
            System.out.println("使用了微信支付");
        }
    }
    
    /**
     * 支付宝支付处理类
     *
     * @author ZXP
     * @date 2021/12/4 21:29
     */
    @Service
    public class AliPayServiceImpl implements PayService {
    
        @Override
        public PayEnum getPayType() {
            return PayEnum.ALIPAY;
        }
    
        @Override
        public void pay(Object obj) {
            // 支付宝支付的逻辑
            System.out.println("使用了支付宝支付");
        }
    }
    
  4. 定义支付处理类工厂PayServiceFactory,管理所有PayService的实现类,该类实现了Spring提供的ApplicationContextAware接口,重写setApplicationContext(ApplicationContext applicationContext)方法,可以通过ApplicationContext获取所有PayService的实现类,然后注册到Map中

    /**
     * PayServiceFactory
     *
     * @author ZXP
     * @date 2021/12/4 21:31
     */
    @Component
    public final class PayServiceFactory implements ApplicationContextAware {
    
        private static final Map<PayEnum, PayService> SERVICES = new ConcurrentHashMap<>(16);
    
        /**
         * 通过支付类型获取具体的支付处理类
         *
         * @param payEnum
         * @return
         */
        public static PayService get(PayEnum payEnum) {
            return SERVICES.get(payEnum);
        }
    
        /**
         * 通过code获取支付处理类
         *
         * @param code
         * @return
         */
        public static PayService get(int code) {
            return get(PayEnum.getByCode(code));
        }
    
        /**
         * 注册PayService
         *
         * @param payService
         * @return
         */
        public static void register(PayService payService) {
            SERVICES.put(payService.getPayType(), payService);
        }
    
        /**
         * 初始化方法
         *
         * @param applicationContext
         * @throws BeansException
         */
        @Override
        public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
            // 从容器中获取全部的支付处理类,注册到
            Map<String, PayService> payServices = applicationContext.getBeansOfType(PayService.class);
            for (PayService payService : payServices.values()) {
                // 注册到map中
                register(payService);
            }
        }
    }
    

使用演示

@Test
public void testPay() {
    // 微信支付
    PayServiceFactory.get(PayEnum.WX).pay(new Object());
    // 支付宝支付
    PayServiceFactory.get(PayEnum.ALIPAY).pay(new Object());
}

运行结果:

运行结果

总结

上述使用策略模式将不同支付类型的处理逻辑分发到不同的支付处理类中处理,可读性也较强,之后如果要增加新的支付方式,只需要添加一种枚举类型,新增加一个PayService的实现类即可,PayServiceFactory会自动将所有实现类注册到自己内部的Map中,从而使用时只需要通过支付类型到PayServiceFactory中获取支付处理类即可。

扩展

如若某些类型处理逻辑大致相同,只有某些小步骤不相同,此时可以引入模板方法模式加以处理,大致逻辑时在PayService和实现类之间增加一个抽象类,抽象类中重写相同的方法,某些特定步骤则下沉到具体实现类中处理。
扩展实现:Spring中使用模板方法模式

  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值