23种模式,今天我要讲的是利用策略模式来应付复杂的需求。
拿到一个需求就是,调用百度接口,那么百度那么多接口,后续会不会又要调用其他接口呢,肯定是会变化的,那么我们怎么用好策略模式应对需求呢。
策略模式定义了一系列算法,并将每个算法封装起来,使他们可以相互替换,且算法的变化不会影响到使用算法的客户。需要设计一个接口,为一系列实现类提供统一的方法,多个实现类实现该接口,设计一个抽象类(可有可无,属于辅助类),提供辅助函数,关系图如下:
- 写一个baiduOrcService接口,里面只有一个send方法。代码如下所示:
/**
* 百度文字识别(OCR)服务
*
* @author mjy
*
*/
public interface BaiduOrcService {
boolean send();
}
- 再写一个接口实现类IdCardApi,实现接口的send方法。注入@Component类,为了实现spring boot自动注入,代码如下所示:
import org.springframework.stereotype.Component;
@Component("IdCardApi")
public class IdCardApi implements BaiduOrcService {
@Override
public boolean send() {
System.err.println("id card");
return false;
}
}
- 这个时候最关键的代码,BaiduOrcServiceContext类,注入@service方法,spring boot 能扫描到BaiduOrcServiceContext类。将这个方法放入@ComponentScan能扫描到的包下。代码如下所示:
/**
* 策略模式
*
* @author mjy
*
*/
@Service
public class BaiduOrcServiceContext {
private final Map<String, BaiduOrcService> baiduMap = new ConcurrentHashMap<>();
@Autowired
public BaiduOrcServiceContext(Map<String, BaiduOrcService> baiduMap) {
this.baiduMap.clear();
baiduMap.forEach((k, v) -> this.baiduMap.put(k, v));
}
public boolean send(String api) {
return baiduMap.get(api).send();
}
}
上面的BaiduOrcServiceContext构造类会自动注入所有实现类,通过send方法调用实现类。
- 最后来一段调用代码
/**
* 首页
*
* @author mjy
*
*/
@RestController
@RequestMapping("/api")
public class ApiIndexController {
//自动注入
@Autowired
private BaiduOrcServiceContext baiduOrcServiceContext;
//通过请求/api/send?api=实现类方法名,完成策略模式
@RequestMapping("send")
public boolean send(String api) {
return baiduOrcServiceContext.send(api);
}
}