描述:現有一個電子簽章需求,對接三個三方簽章服務:上上簽、君子簽、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來路由到不同的實現上。