你还在用if-else吗?

本文内容纲要:

- 使用spring容器干掉if-else

- 场景说明

- 解决办法

使用spring容器干掉if-else

场景说明

最近新做一个项目,需要对不同店铺的商品做不同处理。例如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,并且都要在原有的代码上进行修改,耦合度太高,也大大的降低了代码的可维护性。

因此引入本文的重点。

解决办法

这个时候我们会希望可以各个店铺的处理逻辑之间没有关联,互不影响。

抽象接口

我们所有的店铺都会进行对应的操作,所以首先我们将方法抽象出来

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,就交给工厂类来处理。

还是免不了写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.

*/

最后

本文内容总结:使用spring容器干掉if-else,场景说明,解决办法,

原文链接:https://www.cnblogs.com/perryzjl/p/11097106.html

以上是 你还在用if-else吗? 的全部内容, 来源链接: utcz.com/z/296366.html

回到顶部