首页 > 其他分享 >设计模式|责任链模式(Chain of Responsibility Pattern)

设计模式|责任链模式(Chain of Responsibility Pattern)

时间:2024-04-07 21:59:56浏览次数:12  
标签:请求 Chain 处理 Pattern request 模式 责任 Handler 设计模式

文章目录


责任链模式(Chain of Responsibility Pattern)是一种行为设计模式,它允许你创建一个对象链。请求将沿着这个链传递,直到有一个对象处理它为止。这种模式可以使请求的发送者和接收者解耦。
当想让一个以上的对象有机会能够处理同一请求的时候,就可以使用责任链模式(Chanin of Responsibility Pattem)

结构

  1. 抽象处理者(Handler):定义了一个处理请求的接口。通常包含一个指向下一个处理者的引用。
  2. 具体处理者(Concrete Handler):实现了处理请求的具体逻辑。如果能够处理请求,就处理之;否则将请求传递给下一个处理者。

优点

  • 解耦了请求发送者和接收者,增强了系统的灵活性。
  • 可以动态地增加或修改处理者。
  • 简化了对象,每个具体处理者只需关注自己的业务逻辑。

缺点

  • 请求的处理可能会传递到链的末端仍未被处理。
  • 可能会影响性能,特别是在链较长时。
  • 如果链设置不当,可能会导致循环引用。

使用责任链的步骤

为请求创建一个对象链,每个对象依次检查此请求,并对其进行处理,或者将其传递给链中的下一个对象;
链中的每一个对象都需要扮演一个处理器,并且有一个后继对象,如果他可以处理请求,就进行处理,如果不能,就将请求转发给后继者

示例

考虑一个简单的审批流程,包括经理、部门主管和CEO三个级别的审批。在这个场景中,责任链模式可以很好地应用。

// 抽象处理者
abstract class Handler {
    protected Handler successor;

    public void setSuccessor(Handler successor) {
        this.successor = successor;
    }

    public abstract void handleRequest(String request);
}

// 具体处理者1
class Manager extends Handler {
    @Override
    public void handleRequest(String request) {
        if (request.equals("manager")) {
            System.out.println("Manager approved the request.");
        } else {
            System.out.println("Manager cannot handle the request.");
            if (successor != null) {
                successor.handleRequest(request);
            }
        }
    }
}

// 具体处理者2
class DepartmentHead extends Handler {
    @Override
    public void handleRequest(String request) {
        if (request.equals("department_head")) {
            System.out.println("Department Head approved the request.");
        } else {
            System.out.println("Department Head cannot handle the request.");
            if (successor != null) {
                successor.handleRequest(request);
            }
        }
    }
}

// 具体处理者3
class CEO extends Handler {
    @Override
    public void handleRequest(String request) {
        if (request.equals("CEO")) {
            System.out.println("CEO approved the request.");
        } else {
            System.out.println("CEO cannot handle the request.");
            if (successor != null) {
                successor.handleRequest(request);
            }
        }
    }
}

// 客户端
public class Main {
    public static void main(String[] args) {
        // 创建具体处理者对象
        Handler manager = new Manager();
        Handler departmentHead = new DepartmentHead();
        Handler ceo = new CEO();

        // 设置责任链
        manager.setSuccessor(departmentHead);
        departmentHead.setSuccessor(ceo);

        // 发送请求
        manager.handleRequest("department_head");
        manager.handleRequest("manager");
        manager.handleRequest("CEO");
        manager.handleRequest("other");
    }
}

在这个示例中,**Handler**是抽象处理者,包含了一个指向下一个处理者的引用。 **Manager** DepartmentHeadCEO是具体的处理者,它们实现了handleRequest`方法来处理请求。在客户端代码中,首先创建具体处理者对象,然后设置责任链,并发送请求。

有哪些知名框架采用了责任链模式

责任链模式在许多知名的框架和库中都有应用。以下是一些采用责任链模式的知名框架和库的例子:

  1. Java Servlet 中的 Filter Chain:Java Servlet 中的过滤器(Filter)是一个典型的责任链模式的实现。多个过滤器按照顺序组成一个链,每个过滤器都有机会处理请求,或将请求传递给下一个过滤器。
  2. Spring 框架中的拦截器(Interceptor):Spring 框架中的拦截器也是一种责任链模式的应用。拦截器可以在控制器方法执行之前或之后执行特定的逻辑,多个拦截器按照配置顺序形成一个链。
  3. Node.js 中的 Connect 和 Express 框架:Connect 和 Express 框架中的中间件(Middleware)也采用了责任链模式的思想。多个中间件按照顺序组成一个链,每个中间件都有机会处理请求,或将请求传递给下一个中间件。
  4. .NET Core 中的中间件:在 .NET Core 中,使用中间件来处理 HTTP 请求。类似于 Node.js 中的中间件,中间件按照顺序形成一个链,每个中间件都有机会处理请求,或将请求传递给下一个中间件。
  5. Android 中的事件传递机制:在 Android 中,事件传递机制也可以看作是责任链模式的一种应用。当用户触摸屏幕时,事件首先传递给顶层的 View,然后逐级向下传递,直到某个 View 处理了事件为止。

这些是一些采用责任链模式的知名框架和库的例子,它们充分利用了责任链模式的灵活性和可扩展性,使得代码更加模块化和易于维护。

责任链模式和链表有什么关联

责任链模式和链表之间有一些相似之处,主要体现在它们的结构特点和数据流动方式上。具体来说,它们的关联在于:

  1. 链式结构:
  • 责任链模式中的处理者对象按照一定的顺序连接成链,每个处理者都持有对下一个处理者的引用。这种结构类似于链表中节点之间的链接。
  • 链表也是一种链式结构,由节点组成,每个节点包含对下一个节点的引用。
  1. 数据流动:
  • 在责任链模式中,请求沿着责任链流动,每个处理者都有机会处理请求或将请求传递给下一个处理者。这种数据的传递和处理方式类似于链表中数据元素的遍历。
  • 链表中的数据元素通过节点之间的引用进行流动和访问,可以顺序地遍历整个链表。

虽然责任链模式和链表在结构上有相似之处,并且都涉及到数据的顺序流动,但它们的目的和应用场景不同。责任链模式用于实现请求的传递和处理,而链表用于组织和存储数据。因此,虽然有关联,但它们在概念上和实际应用中的作用是不同的。

常见面试题

在面试中,关于责任链模式的问题可能涉及其原理、优缺点、应用场景以及实际应用等方面。以下是一些可能的问题以及相应的答案:

  1. 责任链模式的原理是什么?
    答案: 责任链模式是一种行为设计模式,其中多个对象按照顺序组成链,每个对象都有机会处理请求或将请求传递给下一个对象。请求在链上传递,直到被处理或者达到链的末端。
  2. 责任链模式的优点有哪些?
    答案:
  • 解耦了请求发送者和接收者,增强了系统的灵活性和可维护性。
  • 可以动态地增加或修改处理者,无需修改客户端代码。
  • 简化了对象,每个具体处理者只需关注自己的业务逻辑。
  1. 责任链模式的缺点是什么?
    答案:
  • 可能会导致请求的处理延迟,特别是在链较长时。
  • 如果责任链设置不当,可能会导致请求无法被处理或形成循环引用。
  • 请求可能会到达链的末端仍未被处理。
  1. 责任链模式在什么情况下适用?
    答案:
  • 当有多个对象可以处理同一请求,但具体处理者未知时。
  • 当需要在运行时动态确定处理请求的对象时。
  • 当想要将请求的发送者和接收者解耦时。
  1. 能否举例说明一个实际应用场景中如何使用责任链模式?
    答案: 例如,在一个在线购物系统中,可以应用责任链模式来处理退款请求。不同级别的管理人员可以处理不同金额范围的退款请求,如普通员工可以处理小额退款,主管可以处理中额退款,高级管理人员可以处理大额退款。当有退款请求时,系统首先将请求发送给普通员工,如果金额超出其处理范围,则将请求传递给主管,以此类推,直到有人处理请求或者到达责任链的末端。

标签:请求,Chain,处理,Pattern,request,模式,责任,Handler,设计模式
From: https://blog.csdn.net/weixin_44435110/article/details/137378999

相关文章

  • PHP代码审计——Day6-Frost Pattern
    漏洞解析classTokenStorage{publicfunctionperformAction($action,$data){switch($action){case'create':$this->createToken($data);break;case'delete':......
  • 设计模式-建造者模式
    1.概念建造者模式(BuilderPattern)又叫生成器模式,是一种创建型设计模式,用于将复杂对象的构建过程与其表示分离,以便相同的构建过程可以创建不同的表示。这种模式特别适用于创建那些具有多个组成部分、步骤复杂或者产品具有多种不同变化的对象。2.原理结构图原理结构图......
  • 设计模式 - 代理模式
    使用代理对象,我们可以对与某些对象的交互进行更多的控制。代理对象可以在我们与对象进行交互时确定其行为,例如,当我们获取值或设置值时。一般来说,代理是指代替他人的人。你不是直接和那个人说话,而是和代表你试图联系的人说话的代理。在JavaScript中也是如此:我们不是直接与目标......
  • C++设计模式:TemplateMethod模式(一)
    1、概念定义定义一个操作中的算法的骨架结构(稳定),而将一些步骤延迟(变化)到子类中。TemplateMethod使得子类可以不改变(复用)一个算法的骨架结构即可重定义(override重写)该算法的某些特定步骤在软件构建过程中,对于某一项任务,它常常有稳定的整体操作结构,但是各个子步骤却有很......
  • 毅四捕Go设计模式笔记——桥接模式
    桥接模式(BridgePattern)桥接模式是一种结构型设计模式,它的主要目的是将抽象部分与它的实现部分解耦,使它们都可以独立的变化。通过使用组合而非继承的方式,桥接模式结合了两个独立的维度,让它们可以独立扩展而不是在两者之间建立静态的继承关系。为了解决什么问题?桥接模式解......
  • [Microservices] Microservices Anti-Patterns
    Whiletherearemanypatternsfordoingmicroserviceswell,anequallysignificantnumberofpatternsexistthatcanquicklygetanydevelopmentteamintotrouble.Thefollowingaresomeofthedon’tswhiledevelopingmicroservices:Don’tbuildmicroservi......
  • 设计模式总结-桥接模式
    桥接模式模式动机模式定义模式结构模式分析桥接模式实例与解析实例一:模拟毛笔模式优缺点模式动机设想如果要绘制矩形、圆形、椭圆、正方形,我们至少需要4个形状类,但是如果绘制的图形需要具有不同的颜色,如红色、绿色、蓝色等,此时至少有如下两种设计方案:第一种设计方......
  • 设计模式总结-适配器模式
    适配器模式模式动机模式定义模式结构适配器模式实例与解析实例一:仿生机器人实例二:加密适配器总结模式动机在软件开发中采用类似于电源适配器的设计和编码技巧被称为适配器模式。通常情况下,客户端可以通过目标类的接口访问它所提供的服务。有时,现有的类可以满足客......
  • 毅四捕Go设计模式笔记——原型模式
    为了解决什么问题?原型模式主要用来解决对象的创建问题,特别是当直接创建对象的成本比较高时(例如,需要复杂的初始化过程,或是创建一个和已存在对象一样的实例)。它允许通过复制一个已存在的实例来返回完全一样的副本,而不需要知道对象的具体类型,并可以在此基础上进行更改。怎么......
  • 设计模式-工厂模式
    作用:提供一个接口,返回子对象将bean注入工厂方式:1.@Component+构造器:AbstractLogicChain实现ILogicChain接口@Component("rule_blacklist")publicclassBlackListLogicChainextendsAbstractLogicChain@Component("default")publicclassDefaultLogicChainex......