描述:现有一个电子签章需求,对接三个三方签章服务:上上签、君子签、e签宝,三方的服务都能完成签章,不同的场景需要调用不同的签章服务完成签章。签章具体实现不做讨论,主要介绍下设计思想。
便于灵活调用,采用策略模式+代理来实现设计:
策略模式的主要角色如下。
- 抽象策略(Strategy)类:定义了一个公共接口,各种不同的算法以不同的方式实现这个接口,环境角色使用这个接口调用不同的算法,一般使用接口或抽象类实现。
- 具体策略(Concrete Strategy)类:实现了抽象策略定义的接口,提供具体的算法实现。
- 环境(Context)类:持有一个策略类的引用,最终给客户端调用。
定义抽象策略:
/**
* @ClassName : AbstractSignHandler
* @Description : 抽象策略类
* @Date : 2021-04-01 13:51
*/
public interface AbstractSignHandler {
String route();
void methodOne();
void methodTwo();
}
具体策略实现,继承抽象策略:上上签、君子签、e签宝
/**
* @ClassName : SSQSignHandler
* @Description : 具体策略--君子签 ,@Component交给Spring管理
* @Date : 2021-04-01 13:56
*/
@Component
public class SSQSignHandler implements AbstractSignHandler {
//路由
@Override
public String route() {
return "ssq";
}
@Override
public void methodOne() {
System.out.println("在这里调用ssq方法A");
}
@Override
public void methodTwo() {
System.out.println("在这里调用ssq方法B");
}
}
/**
* @ClassName : JZQSignHandler
* @Description : 具体策略--君子签 ,@Component交给Spring管理
* @Date : 2021-04-01 13:56
*/
@Component
public class JZQSignHandler implements AbstractSignHandler {
@Override
public String route() {
return "jzq";
}
@Override
public void methodOne() {
System.out.println("在这里调用jzq方法A");
}
@Override
public void methodTwo() {
System.out.println("在这里调用jzq方法B");
}
}
**
* @ClassName : EqbSignHandler
* @Description : 具体策略--e签宝,@Component交给Spring管理
* @Date : 2021-04-01 14:39
*/
public class EqbSignHandler implements AbstractSignHandler {
@Override
public String route() {
return "eqb";
}
@Override
public void methodOne() {
System.out.println("在这里调用eqb方法A");
}
@Override
public void methodTwo() {
System.out.println("在这里调用eqb方法B");
}
}
**
* @ClassName : MyHandlerDelegate
* @Description : 策略模式代理分发
* applicationContext.getBeansOfType()得到抽象策略接口AbstractSignHandler的全部实现(具体策略实现类)
* 组装成Map,key值是具体策略中定义的路由,value是具体的策略类
* @Date : 2021-04-01 14:03
*/
@Component
public class MyHandlerDelegate implements ApplicationContextAware, InitializingBean {
private ApplicationContext applicationContext;
private final Map<String, AbstractSignHandler> handlerMap = new ConcurrentHashMap<>();
//初始化完成,将具体的策略类通过key,value方式存入map中
@Override
public void afterPropertiesSet() throws Exception {
applicationContext.getBeansOfType(AbstractSignHandler.class).forEach((k, v) -> {
if (v.route() == null) {
return;
}
handlerMap.put(v.route(), v);
});
}
//获得applicationContext
@Override
public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
this.applicationContext=applicationContext;
}
//公有的get方法,通过参数路由到具体的策略实现类
public AbstractSignHandler selectHandler(String route){
return handlerMap.get(route);
}
}
调用:
/**
* @ClassName : TestController
* @Date : 2021-04-01 14:25
*/
@RestController
public class TestController {
@Autowired
private MyHandlerDelegate myHandlerDelegate;
@PostMapping("/test")
public void doSomething(){
//调用代理分发类的selectHandler方法,获得具体的策略类,从而调用具体策略类的算法
myHandlerDelegate.selectHandler("ssq").methodOne();
myHandlerDelegate.selectHandler("jzq").methodTwo();
myHandlerDelegate.selectHandler("eqb").methodTwo();
}
}
签章的具体实现和配置略过,在设计思路上,采用策略+代理的模式,便于后续扩展操作,载添加一个三方的时候,只需要继承抽象的策略,
再添加一个具体的实现,调用的时候通过route来路由到不同的实现上。