背景
如果你开发一个新服务需要提供对外接口时,你会怎么做?
比较好的做法是提供给前端一个统一入口,统一请求体,该请求体有一个serviceId,不同的接口有不同的serviceId,param传参数。
系统根据不同的serviceId自己自动关联到某个Service,那么具体如果实现呢?这里涉及到设计模式中的门面模式。
门面模式介绍
门面:客户端可以调用门面,门面会将所有从客户端发来的请求委派到相应的子系统去。
子系统:子系统并不知道门面的存在,对于子系统而言,门面仅仅是另外一个客户端而已。
工作中使用门面模式
我所负责的服务有时候跟H5前端对接,有时候跟别的服务对接。
他们来请求我的服务时,body统一用以下模板,请求不同的方法替换serviceId即可,serviceId其实就是相当于上面讲的子系统,对于我的服务来说就是对应的service。
http://localhost:2233/XXXServer/api post
body
{
"appId": "mZdML1A38RUSuZR6",
"termId": "111",
"serviceId": "ceps.healthinfo.detail",
"encryptType": "PLAIN",
"param": {
"healthInfoId": 1
},
"sign": null,
"signType": "PLAIN",
"timestamp": "1636510202858",
"version": "1.0.0"
}
复制代码
http://localhost:2233/XXXServer/api 我们叫统一网关,其实就是统一入口。
正常流程是:请求进来时,会先进行入参校验,解密验签,appId & termId进行接口权限校验,流水号MDC设置.....之后通过serviceId在Bean容器找到对应service执行。
那如何通过serviceId找到对应的service呢?
写一个接口包含String ServiceId和执行方法execute,每个service都实现这个接口并重写serviceId和实现各自的方法。
使用@PostConstruct提前初始化好private Map<String, BizService> serviceMap。
根据ServiceId在Map中通过get即可获得该Service就可以执行了。
BizService service = serviceMap.get(req.getServiceId());response = service.execute(req)。
门面模式的优点
优点:
-
减少系统的相互依赖。使用门面模式,所有的依赖都是对门面对象的依赖,与子系统无关
-
提高了灵活性。不管子系统内部如何变化,只要不影响门面对象,任你自由活动。