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

文章首发在公众号(龙台的技术笔记),之后同步到博客园和个人网站: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 {

    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
        implements BaseAuthenticationStrategy {

    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) {
        // 腾讯云二要素认证具体行为
    }

}

最后总结

抛出一个老生常谈的问题, 学习设计模式有什么作用?

设计模式主要是为了应对 代码的复杂性,让其满足 开闭原则,提高代码的 扩展性;合适的场景合理运用的设计模式,可以帮助代码实现 高内聚、低耦合 等的优点

你无法决定别人的代码,但你可以决定自己的。时间充足的情况下, 尽量以重构的方式去写每一行代码

最后希望小伙伴读过文章后有所收获,祝好。

Original: https://www.cnblogs.com/longtaiblog/p/16421929.html
Author: 小马哥不会代码
Title: 图解设计模式:身份认证场景的应用

原创文章受到原创版权保护。转载请注明出处:https://www.johngo689.com/610783/

转载文章受原作者版权保护。转载请注明原作者出处!

(0)

大家都在看

  • Golang中的空字符,似花不是花

    最近在Linux下开发Go程序,发现一个奇怪的问题,在读取Linux系统信息时读到了空字符,导致了程序异常。在 ASSIC中十六进制0为字符NUT,表示为 空字符NULL。但这个字…

    Java 2023年6月16日
    086
  • 凭借SpringBoot整合Neo4j,我理清了《雷神》中错综复杂的人物关系

    原创:微信公众号 码农参上,欢迎分享,转载请保留出处。 哈喽大家好啊,我是Hydra。 虽然…

    Java 2023年6月5日
    097
  • 安利一款Linux远程连接工具,MobaXterm

    ​前言 作为开发或者运维人员,平时工作都是在Windows上使用远程连接工具来连接Linux。现在主流的较为强大的远程连接工具是SecureCRT(主要是公司的技术人员使用)和Xs…

    Java 2023年6月5日
    089
  • java 程序运行的基础知识【Java bytecode】

    每一个JVM线程来说启动的时候都会创建一个私有的线程栈。一个jvm线程栈用来存储栈帧,jvm线程栈和C语言中的栈很类似,它负责管理局部变量、部分运算结果,同时也参与到函数调用和函数…

    Java 2023年6月15日
    059
  • Linux命令三剑客

    1.awk AWK是一种处理文&#x67…

    Java 2023年6月5日
    093
  • 和为k的最大子数组长度(前缀和)

    给定一个数组arr,该数组无序,每一个元素均为正数,在给定一个正整数k,求arr的所有子数组中所有元素相加和为k的最长子数组的长度 例如:arr = [1,2,1,1,1],k=3…

    Java 2023年6月7日
    098
  • Java中对象序列化的作用

    1、序列化是干什么的? 简单说就是为了保存在内存中的各种对象的状态,并且可以把保存的对象状态再读出来。虽然你可以用你自己的各种各样的方法来保存Object States,但是Jav…

    Java 2023年5月29日
    071
  • Java流程控制

    Scanner对象 Java给我们提供了一个可以获得用户的输入的工具类。 java.util.Scanner 是Java5 的新特征,我们可以通过 Scanner类来获取用户的输入…

    Java 2023年6月5日
    077
  • 程序员必备,一款让你提高300%工作效率的神器uTools(附下载地址)

    下载地址:https://www.aliyundrive.com/s/f7PU7QxdxEz uTools 是什么? uTools = your tools(你的工具集) uToo…

    Java 2023年6月6日
    0102
  • C语言求100以内的和的4种方式

    C语言的一个很经典的例子,帮助熟练运行几个循环的写法 方法一(do—while语句) #include main () { int i,sum=0; do { sum=…

    Java 2023年6月9日
    094
  • CSS相关知识及入门

    修饰HTML页面,美化 CSS代码规范 CSS选择器 就是以HTML中的标签名作为选择器名称 选择CSS代码作用于对应标签名的标签上 适用于将相同样式作用于多个同名标签上 给相应的…

    Java 2023年6月6日
    067
  • 负载均衡

    前言 本文基于Dubbo2.6.x版本,中文注释版源码已上传github:xiaoguyu/dubbo 负载均衡,英文名称为Load Balance,其含义就是指将负载(工作任务)…

    Java 2023年6月16日
    092
  • Sharepoint 2013 安装部署系列篇 第二篇 — SQL集群安装

    第一部分 系统集群安装 . 第三部分 安装和配置网络负载均衡在前端web服务器 第四部分 安装和配置sharepoint 场(三层拓扑部署) 以下图片均为sharepoint 20…

    Java 2023年6月7日
    092
  • SpringBoot自动装配初步浅理解

    Created time: May 15, 2022 6:36 PMDone: DoingLast edited time: May 25, 2022 6:13 PMTags: S…

    Java 2023年6月8日
    086
  • java生成随机数、随机英文字母、随机字符串

    以生成4位随机数字举例说明 方式一: (int) (Math.random() * (9999 – 1000 + 1)) + 1000 说明: 随机数范围:1000~9999。 方…

    Java 2023年5月29日
    060
  • IDEA中sout快捷键无效问题

    新手当在一个类文件中进行了一些操作之后,会造成 sout快捷命令无法自动生成。比如操作了 import引入其它包之后。主要是对IDEA操作的不熟悉。 解决办法 Original: …

    Java 2023年6月9日
    0110
亲爱的 Coder【最近整理,可免费获取】👉 最新必读书单  | 👏 面试题下载  | 🌎 免费的AI知识星球