用户注册功能——责任链

用户注册,传入一些参数:UserRegisterReqDTO类

1. 注册用户名是否存在?——责任链

布隆过滤器+redis set结构记录注销的用户名

2. 注册信息验证

定义业务责任链接口,使用责任链对数据进行验证:链上的每个处理器进行不同功能的验证(用户注册参数必填检验、用户注册用户名唯一检验、用户注册检查证件号是否多次注销)

有两种处理方式:

  1. 请求会被 所有的处理器都处理一遍,不存在中途终止的情况,这里参照 MyBatis 拦截器理解。
  2. 二则是处理器链执行请求中,某一处理器执行时,如果不符合自制定规则的话,停止流程,并且剩下未执行处理器就不会被执行,大家参照 SpringMvc 拦截器理解。

本项目两种模式结合使用

2.1 定义顶级责任链处理器验证接口VerifyHandler和一系列处理器实现类:非空字段验证、用户名是否可用、证件号是否多次注销(拉黑)、敏感信息过滤。。。
2.2 定义责任链处理器上下文类,将所有处理器串成一条链实现链式调用:VerifyHandlerChain

VerifyHandlerChain 处理流程如下:

  1. 实现自 InitializingBean 接口,在对应实现方法中获取 IOC 容器中类型为 VerifyHandler 的 Bean,也就是各处理器实现类
  2. 将 VerifyHandler 类型的 Bean 添加到处理器链容器中。
  3. 定义校验方法 verify(),对入参数据展开处理器链的全部调用,如果过程中发现已无需要验证的数据,直接返回。

处理器的先后调用顺序:如果某一个处理器执行时间很长并且过滤数据很少,把它放到最后面执行。

责任链模式的好处:

减少代码的复杂性,让其满足开闭原则,提高代码的扩展性。 

添加一个新的功能,只需在已有代码基础上扩展代码,在写一个处理器实现类,而非修改已有代码

应用场景:

责任链模式常用于请求的预处理、请求的过滤、请求的分发等场景。例如,可以使用责任链模式来实现权限校验、日志记录、异常处理、请求重试等功能。同时,也可以将责任链模式与其他设计模式结合起来,例如装饰器模式、工厂模式、观察者模式等,从而实现更复杂的功能。

当构建责任链时,为什么要定义具体业务责任链接口而不是直接实现抽象责任链类 AbstractChainHandler 呢?

虽然直接实现 AbstractChainHandler 是可行的,但这种方式会导致两个问题:

  1. 冗余标识:所有责任链处理器都需要实现 mark 方法来标识当前类用于处理哪种业务。这样做会增加冗余代码,因为每个处理器类都需要实现相同的接口来提供标识信息。
  2. 可读性降低:当我们想查看项目中有多少责任链业务处理时,可能会看到大量的具体实现类。这种情况下,我们更关注责任链的类别而不是具体的实现类。直接实现 AbstractChainHandler 会导致责任链类别信息被掩盖,降低了代码的可读性。

因此,为了提高代码的可读性和可维护性,以及避免冗余的标识信息,我们采用定义责任链接口的方式。通过定义责任链接口,每个处理器只需实现自己负责的逻辑,而责任链的类别信息可以通过接口的命名和文档来清晰地体现。

这样一来,我们可以更方便地了解责任链的结构和组成,使代码更加简洁、清晰、易于维护和扩展。

 


责任链重构步骤:

  1. 定义一个责任链处理器接口,有一个handler方法。所有子任务都实现该接口,重写handler方法处理具体的业务逻辑。该接口继承 Spring 框架中的排序接口 Ordered,在处理器类中通过getOrder方法设置顺序,实现处理器的按序执行。 
  2. 再创建一个类-责任链上下文容器:定义一个责任链,存储与责任链相应的子任务,将各处理器存在ArrayList中。容器实现 CommandLineRunner 接口,在 SpringBoot 启动完成后,执行run方法将所有处理器类(实现责任链抽象接口的实现类)注册到责任链上下文中。handler方法对责任链内的处理器先排序,再按序执行。
  3. 实现各处理器类,实现责任链处理器接口,重写handler方法(处理具体的业务逻辑)和getOrder方法(执行顺序)
  4. 直接在业务代码中调用上下文容器.handler(),好处是无需再业务代码中写上百行校验代码。

改进:当业务增多,不同业务使用不同的责任链,重复构建责任链处理器接口和上下文容器也会有冗余代码,将这两个基础类抽象出来,作为基础组件库中的通用组件,供所有系统下的业务使用。

  1. 定义抽象责任链处理接口,有handler方法和mark 方法。接口增加 mark 方法,以便不同业务使用不同的标识。假设项目中有两个业务场景:订单下单和用户创建都需要责任链模式去验证,mark 就是用来进行分组,在业务中进行调用责任链时传递不同的 mark 方法参数,通过该参数找到对应的一组责任链具体实现类集合。

  2. 定义抽象责任链上下文,保存责任链处理类的容器从 List 改为了 Map,方便扩展更多的不同业务责任链子类。run与handler方法逻辑不变:run方法将所有处理器类(实现责任链抽象接口的实现类)注册到责任链上下文中。handler方法对责任链内的处理器先排序,再按序执行。

3. 注册缓存穿透

相关推荐

  1. 用户注册功能——责任

    2024-04-28 09:12:04       39 阅读
  2. 网页的用户注册功能

    2024-04-28 09:12:04       48 阅读
  3. c# 责任模式

    2024-04-28 09:12:04       56 阅读
  4. 责任模式

    2024-04-28 09:12:04       56 阅读
  5. 责任模式

    2024-04-28 09:12:04       53 阅读

最近更新

  1. docker php8.1+nginx base 镜像 dockerfile 配置

    2024-04-28 09:12:04       94 阅读
  2. Could not load dynamic library ‘cudart64_100.dll‘

    2024-04-28 09:12:04       100 阅读
  3. 在Django里面运行非项目文件

    2024-04-28 09:12:04       82 阅读
  4. Python语言-面向对象

    2024-04-28 09:12:04       91 阅读

热门阅读

  1. 模拟电子技术实验(十)

    2024-04-28 09:12:04       33 阅读
  2. 快速了解 git 和 github 是什么,30 分钟速通版

    2024-04-28 09:12:04       25 阅读
  3. 江苏宿迁服务器的优势有哪些?

    2024-04-28 09:12:04       32 阅读
  4. MySQL商城数据表(20-29)

    2024-04-28 09:12:04       29 阅读
  5. INITRANS

    2024-04-28 09:12:04       33 阅读
  6. js构造模式的解释和例子和优缺点

    2024-04-28 09:12:04       29 阅读
  7. PostgreSQL的扩展(extensions)-常用的扩展之PostGIS

    2024-04-28 09:12:04       36 阅读
  8. js动态设置css主题(Style-setProperty)

    2024-04-28 09:12:04       35 阅读
  9. js 延迟加载的⽅式有哪些

    2024-04-28 09:12:04       27 阅读
  10. 最短路(Dijkstra, Bellman-Ford, SPFA, Floyd)

    2024-04-28 09:12:04       25 阅读
  11. 数据结构与算法-图论-DFS/BFS

    2024-04-28 09:12:04       26 阅读