关于后端:图解设计模式身份认证场景的应用

41次阅读

共计 2490 个字符,预计需要花费 7 分钟才能阅读完成。

文章首发在公众号(龙台的技术笔记),之后同步到 segmentfault 和集体网站:xiaomage.info

明天和大家聊一聊,如何正当的将多种设计模式放到同一个业务场景中

业务背景

最近接到一个认证的需要,C 端用户在购买公司保险时,须要先进行 实名认证确认身份

为了保障业务复用,独自将认证的逻辑拆分为微服务模块

C 端用户下单购买保险的逻辑大抵如下

先说下对于认证相干的一些基本知识。简略来说,你如何证实你是你本人

一些云服务厂商都会有对于验证身份的付费接口,接下来咱们就以腾讯云姓名、身份证二因素认证为参考进行举例

说完认证常识,咱们再来拆解下用户购买保险的步骤

  1. 用户在前端发动认证行为
  2. 申请通过网关调用保险服务,保险服务调用认证服务
  3. 认证服务调用腾讯云认证付费 API,返回认证后果信息

认证流程

在整个块认证流程中,咱们会解说三种设计模式,依照程序别离是策略、责任链、模板模式

策略模式

定义一组算法类,将每个算法别离封装起来,让它们能够相互替换。策略模式使这些算法在客户端调用它们的时候可能互不影响地变动,客户端代指应用算法的代码

咱们拿认证来说,定义一个认证接口,而后实现二、三、四因素以及人脸识别实现;将这些实现类放到一个 Map 容器中,并和业务规定好对应的标识 Key,通过标识 Key 获取对应的认证策略实现

如果真的像下面这么简略,if-else 判断加上拆解几个认证函数就能够搞得定,还真的不肯定须要策略模式

咱们再延长来看一种简单场景:假如后续不满足于腾讯云的认证,为了保障可用性以及更多的流量,须要对接更多的认证平台

可用性:平台的接口不太可能保障全年百分百可用,须要有容灾降级或者替换计划

更多的流量:腾讯云认证接口限流 100 次 / S

这个时候策略模式的长处就体现进去了,简化代码的复杂性 以及 保障开闭准则,减少程序的健壮性以及可扩展性

后续再减少三方认证平台和认证形式,都不须要改变原有逻辑,增加对应实现即可

责任链模式

在责任链模式中,多个处理器(参照拦截器)顺次解决同一个申请。一个申请先通过 A 处理器解决,而后再把申请传递给 B 处理器,B 处理器解决完后再传递给 C 处理器,以此类推,造成一个链条,链条上的每个处理器 各自承当各自的解决职责

这里次要将责任链模式利用于,躲避无意义调用三方认证服务

  1. 已认证过的人员信息,在有效期内没必要再次调用
  2. 调用认证后果谬误,仍然会扣钱,比如说名称中蕴含非中文,身份证格局谬误等等

咱们能够将处理器尽量职责繁多,不便后续其它认证形式的 复用和编排

模板办法

模板办法模式在一个办法中定义一个 算法骨架 ,并将某些步骤推延到 子类中实现 。模板办法模式能够让子类在 不扭转算法整体构造的状况下,从新定义算法中的某些步骤

模版办法次要作用:复用性 扩展性

  • 复用性:核心思想就是 父级定义公共实现 由子级进行调取应用
  • 扩展性:在不批改办法逻辑的前提下,变更其中的某些步骤

艰深来讲 : 定义一个抽象类 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) {// 腾讯云二因素认证具体行为}

}

最初总结

抛出一个陈词滥调的问题,学习设计模式有什么作用?

设计模式次要是为了应答 代码的复杂性 ,让其满足 开闭准则 ,进步代码的 扩展性 ;适合的场景正当使用的设计模式,能够帮忙代码实现 高内聚、低耦合 等的长处

你无奈决定他人的代码,但你能够决定本人的。工夫短缺的状况下,尽量以重构的形式去写每一行代码

最初心愿小伙伴读过文章后有所播种,祝好。

正文完
 0