• 设计模式20——职责链模式


    写文章的初心主要是用来帮助自己快速的回忆这个模式该怎么用,主要是下面的UML图可以起到大作用,在你学习过一遍以后可能会遗忘,忘记了不要紧,只要看一眼UML图就能想起来了。同时也请大家多多指教。

    职责链模式(Chain of Responsibility)

    是一种行为型模式。

    目录

    一、概述

    1.1、直观的理解:

    1.2、主要角色:

    1.3、描述对象之间关系的UML图:

    1.4、适用场景:

    二、简单举例

    2.1、对象之间的关系用UML图表示如下:

    2.2、Java代码如下:


     

    一、概述

    1、使多个对象都有机会处理请求,从而避免请求的发送者和接收者之间的耦合关系。将这些对象连成一条链,并沿着这条链传递该请求,直到有一个对象处理它为止。
    
    2、职责链可简化对象的相互连接,它们仅需保持一个指向其后继者的引用,而不需保持它所有的候选接收者的引用。
    3、可以随时增加或修改处理一个请求的结构,增强了给对象指派职责的灵活性。

    1.1、直观的理解

    假设有三个处理请求者,它们组成一个处理链1-》2-》3:

    391a137eaf604dd798d7bbb095417ae8.png

    当遇到请求后的处理步骤如下:

    1a0040b997a94277b76ae43f5b5ff366.png

    可以看到,如果前面的处理请求者能够处理此次请求,那么就不会再把请求传递到后面。这很像if-else语句。

    1.2、主要角色:

    • 处理请求者:处理请求的抽象类或接口 + 处理请求类
    • 发起请求者

    (注:请求链要按需填装配置以后才可以正常使用)

    1.3、描述对象之间关系的UML图:

    faa56208ed164991b5546ca160d0e173.png

    1.4、适用场景:

    • 有多个对象可以处理一个请求,并且具体是哪个对象处理是在运行时自动确定
    • 你想在不明确指定哪个接收者时,向多个对象中的一个提交一个请求
    • 可处理一个请求的对象集合应该被动态指定

    二、简单举例

    现在有三个处理请求者A、B、C,它们分别能够处理的请求参数的范围为:0到9、10到19、20到29。以处理者请求A为头将他们按顺序串在一起,然后请求发起者给处理者请求A发送4个请求。例子简单就不再详细分析了。你可以把这当做一个模板,然后灵活使用:

    2.1、对象之间的关系用UML图表示如下:

    b1bccd44b70e4f348a92920ef57fac87.png

    2.2、Java代码如下:

    处理请求者的抽象类

    1. abstract class Handler {
    2. protected Handler successor;
    3. public void setSuccessor(Handler successor) {
    4. this.successor = successor;
    5. }
    6. public abstract void handleRequest(int request);
    7. }

    处理请求类A:

    1. public class ConcreteHandlerA extends Handler {
    2. @Override
    3. public void handleRequest(int request) {
    4. if (request >= 0 && request < 10) {
    5. System.out.println(this.getClass().getSimpleName() + "处理请求" + request);
    6. } else if (this.successor != null) {
    7. this.successor.handleRequest(request);
    8. }
    9. }
    10. }

    处理请求类B:

    1. public class ConcreteHandlerB extends Handler {
    2. @Override
    3. public void handleRequest(int request) {
    4. if (request >= 10 && request < 20) {
    5. System.out.println(this.getClass().getSimpleName() + "处理请求" + request);
    6. } else if (this.successor != null) {
    7. this.successor.handleRequest(request);
    8. }
    9. }
    10. }

    处理请求类C:

    1. public class ConcreteHandlerC extends Handler {
    2. @Override
    3. public void handleRequest(int request) {
    4. if (request >= 20 && request < 30) {
    5. System.out.println(this.getClass().getSimpleName() + "处理请求" + request);
    6. } else if (this.successor != null) {
    7. this.successor.handleRequest(request);
    8. }
    9. }
    10. }

    主程序(发起请求的类):

    1. public class Main {
    2. public static void main(String[] args) {
    3. Handler handlerA = new ConcreteHandlerA();
    4. Handler handlerB = new ConcreteHandlerB();
    5. Handler handlerC = new ConcreteHandlerC();
    6. //串联ABC
    7. handlerA.setSuccessor(handlerB);
    8. handlerB.setSuccessor(handlerC);
    9. //发送请求
    10. int[] requests = {1, 14, 25, 36};
    11. for (int request : requests) {
    12. handlerA.handleRequest(request);
    13. }
    14. }
    15. }

    这里就不再举例了,可以把上面的Java例子复制到你本地,运行main函数试一下加深理解。这些代码都是我自己学习的时候根据一些教材手敲的,不存在bug可以直接运行。

    如果觉得本文还不错,就请点个赞给作者一点鼓励吧!如果有建议,也请评论指教和讨论!

    d45e9daabb974f29b85a026b7214c2f5.jpeg

     

  • 相关阅读:
    C++ PCL点云局部颜色变换
    面向目标的多模态情感分析方法
    代码中的软件工程:正则表达式十步通关
    R语言剔除时间序列数据中存在的趋势(trend):使用lm函数拟合线性回归模型、使用原始时间序列值减去线性回归线剔除趋势分量
    人工神经网络与遗传算法,遗传算法和神经算法
    基于SqlSugar的开发框架循序渐进介绍(8)-- 在基类函数封装实现用户操作日志记录
    海量数据存储ClickHouse
    5G VONR
    python 表白代码 biu 比心
    dtcloud 的消息机制(二)
  • 原文地址:https://blog.csdn.net/weixin_43687024/article/details/139283975