共计 2490 个字符,预计需要花费 7 分钟才能阅读完成。
文章首发在公众号(龙台的技术笔记),之后同步到 segmentfault 和集体网站:xiaomage.info
明天和大家聊一聊,如何正当的将多种设计模式放到同一个业务场景中
业务背景
最近接到一个认证的需要,C 端用户在购买公司保险时,须要先进行 实名认证确认身份
为了保障业务复用,独自将认证的逻辑拆分为微服务模块
C 端用户下单购买保险的逻辑大抵如下
先说下对于认证相干的一些基本知识。简略来说,你如何证实你是你本人
一些云服务厂商都会有对于验证身份的付费接口,接下来咱们就以腾讯云姓名、身份证二因素认证为参考进行举例
说完认证常识,咱们再来拆解下用户购买保险的步骤
- 用户在前端发动认证行为
- 申请通过网关调用保险服务,保险服务调用认证服务
- 认证服务调用腾讯云认证付费 API,返回认证后果信息
认证流程
在整个块认证流程中,咱们会解说三种设计模式,依照程序别离是策略、责任链、模板模式
策略模式
定义一组算法类,将每个算法别离封装起来,让它们能够相互替换。策略模式使这些算法在客户端调用它们的时候可能互不影响地变动,客户端代指应用算法的代码
咱们拿认证来说,定义一个认证接口,而后实现二、三、四因素以及人脸识别实现;将这些实现类放到一个 Map 容器中,并和业务规定好对应的标识 Key,通过标识 Key 获取对应的认证策略实现
如果真的像下面这么简略,if-else 判断加上拆解几个认证函数就能够搞得定,还真的不肯定须要策略模式
咱们再延长来看一种简单场景:假如后续不满足于腾讯云的认证,为了保障可用性以及更多的流量,须要对接更多的认证平台
可用性:平台的接口不太可能保障全年百分百可用,须要有容灾降级或者替换计划
更多的流量:腾讯云认证接口限流 100 次 / S
这个时候策略模式的长处就体现进去了,简化代码的复杂性 以及 保障开闭准则,减少程序的健壮性以及可扩展性
后续再减少三方认证平台和认证形式,都不须要改变原有逻辑,增加对应实现即可
责任链模式
在责任链模式中,多个处理器(参照拦截器)顺次解决同一个申请。一个申请先通过 A 处理器解决,而后再把申请传递给 B 处理器,B 处理器解决完后再传递给 C 处理器,以此类推,造成一个链条,链条上的每个处理器 各自承当各自的解决职责
这里次要将责任链模式利用于,躲避无意义调用三方认证服务
- 已认证过的人员信息,在有效期内没必要再次调用
- 调用认证后果谬误,仍然会扣钱,比如说名称中蕴含非中文,身份证格局谬误等等
咱们能够将处理器尽量职责繁多,不便后续其它认证形式的 复用和编排
模板办法
模板办法模式在一个办法中定义一个 算法骨架 ,并将某些步骤推延到 子类中实现 。模板办法模式能够让子类在 不扭转算法整体构造的状况下,从新定义算法中的某些步骤
模版办法次要作用:复用性 和 扩展性
- 复用性:核心思想就是 父级定义公共实现 , 由子级进行调取应用
- 扩展性:在不批改办法逻辑的前提下,变更其中的某些步骤
艰深来讲 : 定义一个抽象类 AbstractTemplate
,并定义一个或若干形象办法 abstractMethod
。代码大抵如下:
public abstract class AbstractAuthenticationService<T extends AuthenticationRequest> {void before(T request) { }
void after(T request) { }
// 形象办法
protected abstract void practicalExecute(T request);
public void authentication(T request) {
// 前置拦挡操作,包含不限于责任链模式调用
before(request);
// 策略模式实现,调用具体认证类,比方二因素认证或三要素认证
practicalExecute(request);
// 资源清理或记录认证实现信息
after(request);
}
腾讯云二因素认证实现类,代码如下:
@Slf4j
@Component
@RequiredArgsConstructor
// BaseAuthenticationStrategy 是策略模式实现,定义了 mark、execute 办法
public class NameIdCardAuthenticationByTencentResolver extends AbstractAuthenticationService<NameIdCardAuthenticationReqDTO>
implements BaseAuthenticationStrategy<NameIdCardAuthenticationReqDTO> {
private static final String SUCCESS = "0";
// 责任链容器
private final NameIdCardHandlerChain nameIdCardHandlerChain;
@Override
public String mark() {return AuthenticationEnum.TENCENT.name();
}
@Override
public void execute(NameIdCardAuthenticationReqDTO request) {authentication(request);
}
@Override
public void before(NameIdCardAuthenticationReqDTO request) {
// 责任链调用
nameIdCardHandlerChain.doFilter(request);
}
@Override
public void practicalExecute(NameIdCardAuthenticationReqDTO request) {// 腾讯云二因素认证具体行为}
}
最初总结
抛出一个陈词滥调的问题,学习设计模式有什么作用?
设计模式次要是为了应答 代码的复杂性 ,让其满足 开闭准则 ,进步代码的 扩展性 ;适合的场景正当使用的设计模式,能够帮忙代码实现 高内聚、低耦合 等的长处
你无奈决定他人的代码,但你能够决定本人的。工夫短缺的状况下,尽量以重构的形式去写每一行代码
最初心愿小伙伴读过文章后有所播种,祝好。