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

  • 相关阅读:
    CORS详解
    JBoss 系列九十九:Rest WebService jBPM 6 集成演示样例
    atitit。浏览器缓存机制 and 微信浏览器防止缓存的设计 attilax 总结
    4G时代来临,运营商为谁搭台献唱?
    Pascal&#39;s Triangle II
    cocos2d-x 3.6版连连看载入资源
    SlidingMenu导入编译用法--Eclipse和IDEA
    【解决】hive动态添加partitions不能超过100的问题
    AngularJS clone directive 指令复制
    AndroidStudio文件夹结构视图讲解
  • 原文地址:https://www.cnblogs.com/bailiyi/p/12115027.html
Copyright © 2011-2022 走看看