最近有一个需求 根据不同的地区的类型 返回不同医保地址
常规做法就是使用if来判断不同的地区类型 然后做对应的医保地址返回,例如:
if("类型1".equals("地区类型")){
return 地区类型1的url;
}else if("类型2".equals("地区类型")){
return 地区类型2的url;
}else if("类型3".equals("地区类型")){
return 地区类型3的url;
}
......
但是这种写法一旦后面多一个判断,意味着代码这个地方就需要增加一个分支,而开发有一个开闭原则,就是对代码的修改是关闭的,但可以添加代码来实现后续功能,所以接下来就是我要使用的方式---策略模式,每当多出一个判断分支,我只需要添加一个对用实现类就可以了,具体的写法如下:
1.定义一个接口,
public interface ybUrlInterface{
//获取地区
public String getLocal();
获取医保地址
public String getUrl();
}
2.每个判断就加一个具体的实现类
public class local1 implements ybUrlInterface{
@Override
public String getLocal() {
return "地区1的常量";
}
@Override
public String getYbUrl(String infno) {
return "地区1的医保地址信息";
}
}
public class local2 implements ybUrlInterface{
@Override
public String getLocal() {
return "地区2的常量";
}
@Override
public String getYbUrl(String infno) {
return "地区2的医保地址信息";
}
}
3.最后做一个调度策略模式的类,让我们需要调用的地方来调用这个类
@Component
public class YbUrlHandler implements ApplicationContextAware, InitializingBean {
//容器初始化之后用来装装我们具体的实现类的一个MAP
private final Map<String, YbUrlInterface> handlerMap = new ConcurrentHashMap<>();
//spring容器的核心对象,这里具体不做过多解释,就是用来装对象和初始化对象的
private ApplicationContext applicationContext;
/**
* 重写初始化完成之后把医保的实现类都存到MAP里,键为类型,值为具体的实现对象
* @throws Exception
*/
@Override
public void afterPropertiesSet() throws Exception {
applicationContext.getBeansOfType(YbUrlInterface.class).forEach((k, v) -> {
if (v.getLocal() == null) {
return;
}
handlerMap.put(v.getLocal(), v);
});
}
/**
* 重写给applicationContext初始化赋值
* @param applicationContext
* @throws BeansException
*/
@Override
public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
this.applicationContext=applicationContext;
}
/**
* 具体的根据类型调用具体的医保实现类
* @param info
* @return
*/
public String getYbUrl(String type){
return handlerMap.get(type).getYbUrl();
}
4.最后我们的程序部分就可以使用下面的方式来调用策略模式了
@Autowired
private YbUrlHandler ybUrlHandler;
String ybUrl = ybUrlHandler.getYbUrl("地区1");
其实这个地方最难理解的就是策略模式的调度类,那里相当于就是在spring初始化的时候,把接口的全部实现类都存到了一个集合里面,集合的key就是地区类型,value就是具体的实现类,然后调用的时候根据不同的key是调用不同的实现类的方法,这种做法的灵活在于我不需要改动原来的代码,如果后面增加了新的地区,我只需要新增一个地区3的实现类即可,对原来的代码逻辑不需要调整和修改