你还在用if-else吗?

做者:蜗蜗小小牛html

连接:https://www.cnblogs.com/perryzjl/p/11097106.htmljava

 

使用spring容器干掉if-else

场景说明spring

最近新作一个项目,须要对不一样店铺的商品作不一样处理。例如storeA须要进行handleA操做,storeB须要进行handleB操做,如此类推架构

你们很容易会想到下面的实现方法并发

 
public void handle(String storeName) { //店铺A作操做handleA处理 if(storeName.equals("storeA")) { handleA(); } else if (storeName.equals("storeB")) { handleB(); //店铺B作操做handleB处理 } else { //其余处理 } }

确实上面的代码实现简单易懂,可是若是店铺愈来愈多,操做也愈来愈多的状况下,每新增一个店铺都须要在这里添加一次if else,大大的下降了代码的可维护性。分布式

解决办法ide

这个时候咱们会但愿能够各个店铺的处理逻辑之间没有关联,互不影响。微服务

抽象接口高并发

咱们全部的店铺都会进行对应的操做,因此首先咱们将方法抽象出来源码分析

 
public interface Store { void handle(); }

根据不一样店铺作不一样处理

 
@Service("storeA") public class StoreA implements Store { @Override void handle() { //handleA操做 } } @Service("storeB") public class StoreB implements Store { @Override void handle() { //handleB操做 } }

添加工厂类

这样仍是有问题,由于仍是要在业务代码中写if-else来判断究竟是哪家store来进行操做,这个时候能够写一个工厂类。

 
public class StoreFactory { @Autowired @Qualifier("storeA") private StoreA storeAA; @Autowired @Qualifier("storeB") private StoreB storeBB; //其余实现对象 public Store getStore(String storeName) { if (storeName.equals("storeA")) { return storeAA; } else if (storeName.equals("storeB")) { return storeBB; }//其余的条件下,返回其余的对象 } }

添加工厂类后,咱们在要获取店铺store时只须要调用getStore(String storeName)并传入店铺对象名便可,具体返回哪一个对象,是storeA仍是storeB,就交给工厂类来处理。

想免费学习Java工程化、分布式架构、高并发、高性能、深刻浅出、微服务架构、SpringMyBatisNetty源码分析等技术的朋友,能够加群:834962734,群里有阿里大牛直播讲解技术,以及Java大型互联网技术的视频免费分享给你们,欢迎进群一块儿深刻交流学习无论你是转行,仍是工做中想提高本身能力均可以

仍是免不了写if else,改造StoreFactory

在提供了工厂类以后,仍是免不了写不少的条件判断,只不过是把全部的条件判断写在了一块儿。这时随着产品数量的增多,if else 也会不停地增多,维护起来依然费劲。

这里spring容器就能够派上用场了。spring中有一个BeanFactory对象,也是一个工厂,咱们能够用它来改造StoreFactory。

 
public class StoreFactory { @Autowired private BeanFactory beanFactory; public Store getStore(String storeName) { Object bean = beanFactory.getBean(storeName); if (bean instanceof Store) { return (Store) bean; } throw new UnsupportedOperationException("不支持的店铺:" + storeName); } }

也能够利用Map自动装配进行代码精简

 
@Service public class StoreFactory { @Autowired Map<String, Store> stores = new ConcurrentHashMap<>(); //会在初始化的时候将全部的Store自动加载到Map中 public Store getStore(String store) { Store store = stores.get(store); if (store == null) { throw new RuntimeException("no store defined"); } return store; } }

@Autowired的源码中有这样一段注释,大意就是@Autowired用于Collection或者Map类型时,容器会自动装配全部已声明的value类型的beans。

 
/* <p>In case of a {@link java.util.Collection} or {@link java.util.Map} dependency type, * the container autowires all beans matching the declared value type. For such purposes, * the map keys must be declared as type String which will be resolved to the corresponding * bean names. Such a container-provided collection will be ordered, taking into account * {@link org.springframework.core.Ordered}/{@link org.springframework.core.annotation.Order} * values of the target components, otherwise following their registration order in the * container. Alternatively, a single matching target bean may also be a generally typed * {@code Collection} or {@code Map} itself, getting injected as such. */

以上就是所有内容。

相关文章
相关标签/搜索