zoukankan      html  css  js  c++  java
  • 一种简洁的Spring Bean选择器模式

    作用

    在日常开发中,我们常常会遇到一个接口有多个实现类时,需要选择合适的实现类的情况。

    最简单的方法是写一个选择器,用if-else来判断使用哪个实现类的实例,比如:

    if(条件1){
      return 实现类a的实例;
    }else if(条件2){
      retuen 实现类b的实例;
    }
    

    然而这种方法不符合开闭原则(OCP),如果再添加一个实现类,那么选择器的代码也需要再加一个else if。

    所以,在参考了同事及网上的一些代码后,我整理出了一种简洁的、符合设计原则的实现方式。

    一种更好的选择器:工具类

    这种选择器使用了策略模式,并且利用了Spring的自动注入特性。

    首先,我们需要提供4个工具类:

    public interface MatchingBean<K> {
        boolean matching(K factor);
    }
    
    public interface MyFactoryList<E extends MatchingBean<K>, K> extends List<E> {
        E getBean(K factor);
        List<E> getBeanList(K factor);
    }
    
    public class MyFactoryArrayList<E extends MatchingBean<K>, K> extends ArrayList<E>
            implements MyFactoryList<E, K>, Serializable {
        @Override
        public E getBean(K factor) {
            Iterator<E> itr = iterator();
            while (itr.hasNext()) {
                E beanMatch = itr.next();
                if (beanMatch.matching(factor)) {
                    return beanMatch;
                }
            }
            return null;
        }
        @Override
        public List<E> getBeanList(K factor) {
            Iterator<E> itr = iterator();
            while (itr.hasNext()) {
                E beanMatch = itr.next();
                if (!beanMatch.matching(factor)) {
                    itr.remove();
                }
            }
            return this;
        }
    }
    
    public class MyFactoryListEditor extends CustomCollectionEditor {
        public MyFactoryListEditor() {
            super(MyFactoryArrayList.class);
        }
    }
    

    一种更好的选择器:使用示例

    假设我们有个购物接口,有淘宝和京东两个实现。

    那么就让购物接口继承MatchingBean,代码如下:

    public interface BuyService extends MatchingBean<String> {
        public String goShopping();
    }
    

    然后在实现类里实现matching方法,代码如下:

    @Service
    public class JingdongService  implements BuyService {
    
        @Override
        public String goShopping() {
            return "Shopping in Jd";
        }
    
        @Override
        public boolean matching(String factor) {
            return "jd".equals(factor);
        }
    }
    
    @Service
    public class TaobaoService implements BuyService {
    
        @Override
        public String goShopping() {
            return "Shopping in Taobao";
        }
    
        @Override
        public boolean matching(String factor) {
            return "taobao".equals(factor);
        }
    }
    

    最后,咱们写个测试类,看下选择器的使用方法:

    @RunWith(SpringRunner.class)
    @SpringBootTest
    public class TestMyBeanUtil {
    
        @Autowired
        MyFactoryList<BuyService,String> factoryList;
    
        @Test
        public void testOne(){
            BuyService shop = factoryList.getBean("jd");
            System.out.println(shop.goShopping());
        }
    }
    

    参考文献

    https://my.oschina.net/guanhe/blog/1821060

  • 相关阅读:
    Java实现 LeetCode 136 只出现一次的数字
    Java实现 LeetCode 136 只出现一次的数字
    Java实现 LeetCode 136 只出现一次的数字
    Java实现 LeetCode 135 分发糖果
    Java实现 LeetCode 135 分发糖果
    Java实现 LeetCode 135 分发糖果
    Java实现 LeetCode 134 加油站
    Java实现 LeetCode 134 加油站
    Java实现 LeetCode 134 加油站
    Java实现 LeetCode 133 克隆图
  • 原文地址:https://www.cnblogs.com/bailiyi/p/12115027.html
Copyright © 2011-2022 走看看