首页 > 其他分享 >软件设计模式系列之十五——职责链模式

软件设计模式系列之十五——职责链模式

时间:2023-09-25 19:22:45浏览次数:37  
标签:职责 软件设计 模式 责任 处理 对象 十五 请求

1 模式的定义

职责链模式(Chain of Responsibility Pattern)也称为责任链模式,是一种结构型设计模式,用于构建一条对象处理请求的责任链。在这个模式中,多个对象依次处理请求,直到其中一个对象能够处理该请求为止。职责链模式将请求的发送者和接收者解耦,允许多个对象都有机会处理请求,同时可以动态地配置责任链的顺序和组成。

职责链模式的核心思想是将请求沿着一条链传递,每个处理者都可以选择处理请求或将其传递给下一个处理者。这种方式类似于实现一个处理管道,每个管道元素可以选择执行任务或将任务传递给下一个元素。

2 举例说明

为了更好地理解职责链模式,让我们考虑一个实际的例子。审批系统。假设在一个公司中,员工可以提交报销申请,然后需要一系列审批人员逐级审批,包括直属领导、部门总监、人事部门、高层领导。每个审批人员都在自己的权限内考虑是否签字,签完之后将会继续传递给下一级审批人员。这种情况下,可以使用职责链模式来构建一个审批流程。

在这个示例中,每个审批人员都是责任链中的一个节点,他们可以选择批准或拒绝请求,并将请求传递给下一个审批人员,直到有人批准或拒绝为止。

3 结构

职责链模式的结构包括以下几个关键部分:

Handler(处理者):定义一个处理请求的接口,并包含一个指向下一个处理者的引用。处理者可以选择处理请求或将其传递给下一个处理者。

ConcreteHandler(具体处理者):实现处理请求的具体逻辑,如果自己无法处理请求,就将请求传递给下一个处理者。

Client(客户端):创建责任链并将请求发送到责任链的第一个处理者。客户端不需要知道责任链的具体结构,只需将请求发送给第一个处理者即可。

4 实现步骤

实现职责链模式时,通常遵循以下步骤:

定义处理请求的接口(Handler),并在接口中声明处理请求的方法。

创建具体处理者类(ConcreteHandler),实现处理请求的具体逻辑。每个具体处理者都需要包含一个指向下一个处理者的引用。

在具体处理者类中,实现处理请求的逻辑,并在必要时将请求传递给下一个处理者。

在客户端代码中创建责任链,并将请求发送给责任链的第一个处理者。

5 代码实现

现在,让我们通过 Java 代码来实现审批系统的职责链模式。

// 1. 定义处理请求的接口
interface Approver {
    void approveRequest(ExpenseRequest request);
}

// 2. 创建具体处理者类
class TeamLeader implements Approver {
    private Approver nextApprover;

    @Override
    public void approveRequest(ExpenseRequest request) {
        if (request.getAmount() <= 100) {
            System.out.println("Team Leader approved the expense request.");
        } else if (nextApprover != null) {
            nextApprover.approveRequest(request);
        }
    }

    public void setNextApprover(Approver nextApprover) {
        this.nextApprover = nextApprover;
    }
}

class Manager implements Approver {
    private Approver nextApprover;

    @Override
    public void approveRequest(ExpenseRequest request) {
        if (request.getAmount() <= 500) {
            System.out.println("Manager approved the expense request.");
        } else if (nextApprover != null) {
            nextApprover.approveRequest(request);
        }
    }

    public void setNextApprover(Approver nextApprover) {
        this.nextApprover = nextApprover;
    }
}

class FinanceDepartment implements Approver {
    @Override
    public void approveRequest(ExpenseRequest request) {
        System.out.println("Finance Department approved the expense request.");
    }
}

// 3. 客户端代码
public class Client {
    public static void main(String[] args) {
        Approver teamLeader = new TeamLeader();
        Approver manager = new Manager();
        Approver finance = new FinanceDepartment();

        // 构建责任链
        teamLeader.setNextApprover(manager);
        manager.setNextApprover(finance);

        // 提交报销请求
        ExpenseRequest request1 = new ExpenseRequest("John", 80);
        teamLeader.approveRequest(request1);

        ExpenseRequest request2 = new ExpenseRequest("Alice", 300);
        teamLeader.approveRequest(request2);

        ExpenseRequest request3 = new ExpenseRequest("Bob", 800);
        teamLeader.approveRequest(request3);
    }
}

6 典型应用场景

职责链模式在实际应用中有多种典型场景,以下是一些常见的应用。

审批流程:如报销审批、请假审批等,不同级别的审批人员构成责任链,依次处理请求。

事件处理:在图形用户界面(GUI)开发中,事件处理机制可以采用职责链模式,将事件从用户界面传递给各种控件,以便处理用户输入。

日志记录:不同级别的日志记录器可以组成责任链,根据日志级别决定是否记录日志以及如何记录。

异常处理:在程序中处理异常时,可以使用职责链模式来处理不同类型的异常,以便根据异常类型采取不同的处理策略。

权限控制:在系统中控制用户访问权限时,可以使用职责链模式来构建权限控制链,根据用户的权限级别逐级检查并授权。

HTTP请求处理:Web框架中的中间件(Middleware)可以使用职责链模式来处理HTTP请求,例如身份验证、日志记录、缓存等中间件可以依次处理请求。

7 优缺点

优点:

松耦合:职责链模式将请求的发送者和接收者解耦,允许多个对象都有机会处理请求,使系统更加灵活。

动态配置责任链:责任链的顺序和组成可以在运行时动态配置,不需要修改代码即可调整责任链。

可扩展性:可以轻松地添加新的处理者类,扩展责任链,不会影响现有代码。

缺点:

性能问题:如果责任链过长或者处理请求的逻辑复杂,可能会导致性能问题,因为每个请求都需要遍历整个责任链。

请求未处理:如果责任链没有正确配置或者没有合适的处理者来处理请求,可能导致请求无法被处理。

难以调试:责任链模式中,请求的处理路径可能会变得不透明,难以调试和理解。

8 类似模式

与职责链模式类似的模式包括策略模式、装饰器模式和命令模式。这些模式都有一定的相似之处,但它们各自有不同的关注点和应用场景。

策略模式(Strategy Pattern):

策略模式和职责链模式都允许动态地选择不同的对象来处理请求或任务。它们都关注于将请求发送者和接收者解耦,使系统更加灵活。策略模式关注于选择不同的算法或策略来处理特定的任务,它将不同的策略封装成独立的对象,并允许在运行时切换策略。职责链模式关注于多个对象依次处理请求,直到其中一个对象能够处理为止,每个对象都有机会处理请求。

装饰器模式(Decorator Pattern):

装饰器模式和职责链模式都允许动态地包装对象以增强其功能。它们都通过组合来实现,可以链式地将多个装饰器或处理者组合在一起。装饰器模式关注于在不改变接口的情况下增强对象的功能,通常用于为单个对象添加功能。职责链模式关注于将请求从一个对象传递到另一个对象,每个对象都可以选择处理或传递请求。

命令模式(Command Pattern):

命令模式和职责链模式都可以用于将请求的发送者和接收者解耦。它们都关注于将请求封装成对象,允许将请求传递给不同的对象。命令模式关注于将请求封装成命令对象,允许撤销和重做操作,以及延迟执行请求。职责链模式关注于多个对象依次处理请求,直到其中一个对象能够处理为止,不一定涉及命令的封装和执行。

总的来说,这些模式有一些共同之处,包括解耦请求的发送者和接收者,以及支持动态配置和组合对象。然而,它们的关注点和应用场景不同,应根据具体需求来选择合适的模式。在一些情况下,这些模式甚至可以组合使用,以实现更复杂的功能。

9 小结

职责链模式是一种有用的设计模式,它可以帮助构建灵活的责任链,使多个对象能够依次处理请求。通过将请求的发送者和接收者解耦,职责链模式可以实现松耦合的设计,允许在运行时动态配置责任链的顺序和组成。然而,需要注意在设计时考虑性能问题,确保责任链不会过长或过于复杂。职责链模式在实际应用中有多种典型场景,包括审批流程、事件处理、日志记录等。希望本文能够帮助你更好地理解和应用职责链模式。

标签:职责,软件设计,模式,责任,处理,对象,十五,请求
From: https://www.cnblogs.com/coodream2009/p/17728666.html

相关文章

  • 模式识别与机器学习——生成式分类器 课程笔记
    有监督学习:从有标记的数据中学习推断函数目标函数:\(Y=f(x)\)或\(P(Y|X)\)注意:条件概率用小写p表示,先验概率用大写P表示。贝叶斯判别原则给定观测值X,判断其属于\(\omega1\)类还是\(\omega2\)类,最小化误差概率条件下,\(P(\omega1|X)>P(\omega2|X)\)则判断成\(X\in\omega1\),......
  • 单例注册表模式探索
    MazeFactory单例工厂,维护一个单例注册表,每种迷宫子类维护一个单例,这种方式不用破坏原来的代码结构,将单例实现搬到外面,如果维持全局的单例,无论属于何种迷宫均算作一种,,那么就需要提供迷宫的销毁方法,并在getInstance方法中控制单例的交替。还有一种方式是将每个子类设计为单例模式,并......
  • fopen各个模式区别
    fopen函数是C标准库中用于打开文件的函数,它接受一个文件名和一个打开模式作为参数,返回一个指向文件的指针。这里解释各个模式的区别:"r":以只读模式打开文件,文件必须存在,否则返回NULL。文件指针指向文件的开头。用于读取文件内容。"r+":以读写模式打开文件,文件必须......
  • NineData SQL 窗口支持深色模式,让程序员不再怕长期用眼!
    您有没有尝试过被明亮的显示器闪瞎眼的经历? 在夜间或低光环境下,明亮的界面会导致许多用眼健康问题,例如长时间使用导致的眼睛疲劳、干涩和不适感,同时夜间还可能会抑制褪黑素分泌,给您的睡眠质量带来影响。 这些问题对于长期使用电脑的程序员来说是真实存在且对健康非常不利的......
  • FlashDuty Changelog 2023-09-07 | 新增深色模式与主题配置
    FlashDuty:一站式告警响应平台,前往此地址免费体验!FlashDuty现在已经全面支持了深色模式,这为您提供了更柔和的光线和舒适的界面外观。并且,您可以根据自己的喜好和使用环境动态切换深色和浅色模式与主题,提高使用体验的个性化和灵活性。深色模式效果预览为了确保在深色模式下......
  • FlashDuty Changelog 2023-09-07 | 新增深色模式与主题配置
    FlashDuty:一站式告警响应平台,前往此地址免费体验!FlashDuty现在已经全面支持了深色模式,这为您提供了更柔和的光线和舒适的界面外观。并且,您可以根据自己的喜好和使用环境动态切换深色和浅色模式与主题,提高使用体验的个性化和灵活性。深色模式效果预览为了确保在深色模式下能够呈现......
  • 《看了受制了》第二十五天吗,5道题,合计119道题
    2023年9月24日今天下午,把atcoder翻译的弄成了一个ChatGpt的接口版本。优化了很多。牛客周赛13矩阵转置置题面理解就是语法,倒着输出即可。代码实现#include<iostream>#include<algorithm>#include<unordered_map>#include<cstring>#include<cstdio>#include<vect......
  • 实模式和保护模式
    读源码时应该注意的事项在第一遍阅读源码时,已弄懂整体流程为主,至于具体的实现细节先简单的理清处过一遍,不用过于纠结。当梳理清楚全部的框架逻辑后,第二遍再深入的学习研究各个模块的实现,此时应该解决第一遍中的疑惑。第三遍可以跳出代码的实现,来看Linux的设计思路、编程......
  • 设计模式-享元模式
    享元模式模式定义运用共享技术有效的支持大量颗粒度的对象模式动机如果一个应用使用了大量的对象,而大量的对象造成了很大的存储开销时就应该考虑使用当对象的大多数状态为外部状态,如果删除对象的外部状态,那么可以用相对较少的共享内存对象取代很多组对象,此时可以考虑使用......
  • 工厂模式的三种姿态?
    在软件工程中常见的设计模式——工厂模式。工厂模式是一种有力的工具,用于创建对象实例的方式,可以帮助我们更好地组织代码和降低耦合性。在本文中,我将为大家详细介绍工厂模式的三种姿态,同时通过举例和代码演示来帮助大家更好地理解。工厂模式的三种姿态工厂模式是一种创建型设计模......