zoukankan      html  css  js  c++  java
  • 结合Spring特性实现策略模式

    今天我们来了解下设计模式中比较常用的策略模式

    什么是策略模式?

    策略模式定义了一系列的算法,并将每一个算法封装起来,使每个算法可以相互替代,使算法本身和使用算法的客户端分割开来,相互独立。(摘自百度)

    策略模式适用于什么场景?

    一个大功能,它有许多不同类型的实现(策略类),具体根据客户端来决定采用特定的策略类。
    比如下单、物流对接、网关的加签验签等。

    以物流对接为例来比较简单工厂模式和策略模式。

    具体业务为每个物流公司都有它们对应的code,加签方法,物流查询方法

    首先我们定义好接口类

    public interface Logistics {
    
        /**
         * 物流公司唯一标识
         * @return
         */
        String companyCode();
    
        /**
         * 加签
         * @param request
         */
        String sign(SignRequest request);
    
        /**
         * 查询物流信息
         */
        LogisticsInfoResponse queryLogisticsInfo(QueryLogisticsInfoRequest request);
    
    }
    

    对接顺风和圆通

    @service("shunfengLogistics")
    public class ShunfengLogistics implements Logistics {
    
        @Override
        public String companyCode() {
            return "shunfeng";
        }
    
        @Override
        public String sign(SignRequest request) {
            //do your biz
            
            return null;
        }
    
        @Override
        public LogisticsInfoResponse queryLogisticsInfo(QueryLogisticsInfoRequest request) {
            //do your biz
            
            return null;
        }
    }
    
    @service("yuantongLogistics")
    public class YuantongLogistics implements Logistics {
    
        @Override
        public String companyCode() {
            return "yuantong";
        }
    
        @Override
        public String sign(SignRequest request) {
            //do your biz
            
            return null;
        }
    
        @Override
        public LogisticsInfoResponse queryLogisticsInfo(QueryLogisticsInfoRequest request) {
            //do your biz
            
            return null;
        }
    }
    

    简单工厂模式

    public class LogisticsFactory {
    
        @Autowired
        private Logistics shunfengLogistics;
    
        @Autowired
        private Logistics yuantongLogistics;
    
        public Logistics getLogistics(LogisticsRequest request) {
    
            String company = request.getCompanyCode();
    
            if ("shunfeng".equals(company)) {
            
                return shunfengLogistics;
            }
    
            if ("yuantong".equals(company)) {
           
                return yuantongLogistics;
            }
            
            throw new BizException("物流公司类型错误");
        }
    }
    

    每当我们接入一家物流公司的时候都要使LogisticsFactory加一段if分支。这就违反了设计模式的开闭原则

    策略模式结合Spring特性

    其实不结合Spring特性的话,策略模式还是有上述问题存在。
    我们先来准备下spring相关知识

    1.实现InitializingBean接口。相信这个大家并不陌生。就是spring容器创建bean的时候帮你执行初始化的接口

    2.实现ApplicationContextAware接口。通俗的讲,实现了这个接口的bean相当于是拿到了ApplicationContext,相当于整个spring容器的资源。

    3.ApplicationContext接口的getBeansOfType方法。获取整个spring容器中某个类型的bean,返回的是map类型。key对应beanName, value对应bean。

    @Component
    public class LogisticsResolver implements InitializingBean, ApplicationContextAware {
    
        private ApplicationContext applicationContext;
    
        private Map<String, Sign> logisticsHandlerMap = new HashMap<>();
    
        @Override
        public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
            this.applicationContext = applicationContext;
        }
    
        @Override
        public void afterPropertiesSet() {
            Map<String, Sign> beanMap = applicationContext.getBeansOfType(Logistics.class);
            for (String key : beanMap.keySet()) {
                this.logisticsHandlerMap.put(beanMap.get(key).companyCode(), beanMap.get(key));
            }
        }
    
        public Logistics getHandler(String companyCode) {
            return logisticsHandlerMap.get(companyCode);
        }
    
    }
    

    通过spring容器去获取对应的所有实现类,并组装成我们想要的companyCode→bean的map。通过getHandler方法就能拿到对应的实现类。

    但是现在我们每次加一个策略类的时候都交由Spring去管理,只管加就行了

  • 相关阅读:
    【C&数据结构】---关于链表结构的前序插入和后序插入
    【LC_Overview1_5】---学会总结回顾
    【LC_Lesson5】---求最长的公共前缀
    xorm -sum 系列方法实例
    xorm -Alias,Asc,Desc方法实例
    xorm -Find方法实例
    xorm -Exist方法实例
    xorm -Get方法实例
    xorm-创建时间created
    xorm插入数据实例
  • 原文地址:https://www.cnblogs.com/chenshengyue/p/10826087.html
Copyright © 2011-2022 走看看