使用策略模式消除if else
最近项目中遇到如下情况:
有一个操作叫平帐,然后要对多个不同的款项进行平帐,目测有72种。
然后平帐的方法只有一个,在那个平帐方法里面,判断是哪一种款项,然后不同的款项有不同的处理逻辑。
if(款项A){
款项A的处理方法;
}
if(款项B){
款项B的处理方法;
}
if(款项C){
款项C的处理方法;
}
…
这个就很可怕了。
因此使用策略模式来消除掉if else。
先看使用策略模式之后的代码
输出结果
直接通过同一个dohandler方法根据不同的tag去选择处理不同的逻辑
具体逻辑就是:
定一个handler接口,然后各个处理逻辑去实现这个handler接口。
然后定一个client类,这个类里面定义dohandler方法。
当client类初始化的时候,自动将所有的handler类加载到自己的map列表里面,key为对应逻辑的tag。
当调用client的dohandler的方法时候,传入tag,根据tag从map里面找到对应的handler实现类对象。
先看client类
@Component
public class StatementClient<T> implements InitializingBean {
@Autowired
private ApplicationContextHelper applicationContextHelper;
private Map<String, StatementHandle> TypeAndStatementHandle = new ConcurrentHashMap<>();
@Override
public void afterPropertiesSet() throws Exception {
Map<String, StatementHandle> statementHandles = applicationContextHelper.getBeansOfType(StatementHandle.class);
for (Map.Entry<String, StatementHandle> StatementHandle : statementHandles.entrySet()) {
TypeAndStatementHandle
.put(StatementHandle.getValue().getType().getConfigCode(), StatementHandle.getValue());
}
}
public void doHandler(String tag,T t) {
TypeAndStatementHandle.get(tag).process(t);
}
实现 InitializingBean接口会在这个be an初始化后 执行afterPropertiesSet方法
在里面将从ApplicationContextHelper里面获取到的be an 都放到ma p里面去,ma p的ke y为实现的handler的业务ta g,值为该对象。
ApplicationContextHelper是一个实现了ApplicationContextAware接口的工具类
@Component
public class ApplicationContextHelper implements ApplicationContextAware {
ApplicationContext applicationContext;
@Override
public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
this.applicationContext = applicationContext;
}
public <T> T getBean(Class<T> clazz) {
return applicationContext.getBean(clazz);
}
public <T> Map<String, T> getBeansOfType(Class<T> clazz) {
return applicationContext.getBeansOfType(clazz);
}
}
实现这个接口会在spring容器初始化完成之后调用setApplicationContext方法,将ApplicationContext放进去,从而可以拿到spring的容器ApplicationContext,进而使用这个容器获取我们想要的be an 。
再来看定义的handler接口
process为处理方法,getType为获取ta g的方法。 用来在client里面获区分每个handler实体
最后是两个实现类
这样,外面只需要调用StatementClient这个类的dohandler方法传入对应的ta g就行了,里面会自行根据ta g找对应的方法,而不需要if else