设计模式:责任链模式(C#、JAVA、JavaScript、C++、Python、Go、PHP)

news2025/2/26 5:06:17

上一篇《享元模式》                                                                   下一篇《解释器模式》

简介:

责任链模式,它是一种行为型设计模式,它将许多对象连接起来形成一条链,每个对象处理不同的请求,当一个请求从链的首端发出时,会沿着链路的路径依次传递给每一个对象,直到有对象处理该请求为止。

在责任链模式中,每个处理对象都包含对下一个处理对象的引用,请求会沿着这个链一路传递下去,直到找到一个能够处理该请求的处理对象。在这种模式下,请求的发送者并不知道哪个对象会处理该请求,因此系统可以在不影响客户端的情况下动态地重新组织和分配责任。

责任链模式的使用场景:
1、多个对象可以处理同一个请求,但具体由哪个对象处理则在运行时动态决定。
2、在请求处理者不明确的情况下,向多个对象中的一个提交一个请求。
3、需要动态处理一组对象处理请求。

责任链模式的创建步骤:
1、定义一个抽象的处理器(Handler)接口,其中包含处理请求的方法以及设置下一个处理器的引用。例如:type Handler interface { SetNext(handler Handler) Handle(request interface{}) }。
2、创建具体的处理器类型,并且实现Handler接口。在处理请求时,如果当前处理器无法处理该请求,则将请求转发给下一个处理器。
3、将具体处理器初始化到链条中,并做抽象方法的具体实现。
4、设计链条结束标识,例如通过pos游标。

在实现责任链模式时,需要注意以下几点:
1、每个处理器都需要能够找到下一个处理器,因此需要在Handler接口中设置下一个处理器的引用。
2、每个处理器都需要能够处理其能够处理的请求,如果当前处理器无法处理该请求,则需要将请求转发给下一个处理器。
3、在设计链条时,需要注意如何将处理器正确地连接起来,以避免出现无限循环的情况。
4、在设计链条时,还需要考虑如何处理多个处理器同时能够处理同一请求的情况。

责任链模式的优点,主要包括:
1、降低对象之间的耦合度:责任链模式使得一个对象无须知道到底是哪一个对象处理其请求以及链的结构,发送者和接收者也无须拥有对方的明确信息。
2、增强系统的可扩展性:可以根据需要增加新的请求处理类,满足开闭原则。
3、增强给对象指派职责的灵活性:当工作流程发生变化时,可以动态地改变链内的成员或者调动它们的次序,也可动态地新增或者删除责任。
4、简化对象之间的连接:每个对象只需保持一个指向其后继者的引用,不需保持其他所有处理者的引用,这避免了使用众多的if或者if···else语句。
5、责任分担:每个类只需要处理自己该处理的工作,不该处理的传递给下一个对象完成,明确各类的责任范围,符合类的单一职责原则。

责任链模式的缺点,主要包括:
1、性能问题:每个请求都需要从链表头遍历到链表尾,特别是在链表比较长的情况下,性能会受到很大影响。
2、调试不方便:特别是当链表比较长,环节比较多的时候,由于采用了类似递归的方式,调试时可能逻辑比较复杂。

示例:

一、C#责任链模式

以下是一个示例,展示了如何在C#中实现责任链模式:

using System;  
  
//定义一个处理者接口  
public interface IHandler  
{  
    void HandleRequest();  
}  
  
//定义具体的处理者类1  
public class Handler1 : IHandler  
{  
    public void HandleRequest()  
    {  
        Console.WriteLine("Handler1处理请求"); 
    }  
}  
  
//定义具体的处理者类2  
public class Handler2 : IHandler  
{  
    public void HandleRequest()  
    {  
        Console.WriteLine("Handler2处理请求");  
    }  
}  
  
//定义请求类  
public class Request  
{  
    private string requestType;
    public Request(string requestType){ 
		this.requestType = requestType;
	}  
    public string GetRequestType(){
		return this.requestType;
	}  
}  
//定义请求处理器(RequestProcessor)类,它持有一个处理者(Handler)的引用,并调用它的handleRequest方法。如果当前处理者不能处理该请求,它将请求传递给链中的下一个处理者。  
public class RequestProcessor {  
    private IHandler handler;  
  
    public RequestProcessor(IHandler handler) {  
        this.handler = handler;  
    }  
  
    public void ProcessRequest(Request request) {  
        handler.handleRequest();  
    }  
}
//使用示例:
class Program  
{  
    static void Main(string[] args)  
    {  		
		IHandler handler1 = new Handler1();  
        IHandler handler2 = new Handler2();  
		
        Request request1 = new Request("Request1");  
        Request request2 = new Request("Request2");  
		
		RequestProcessor processor1 = new RequestProcessor(handler1);  
        processor1.ProcessRequest(request1);  // 输出 "Handler1 handled the request."  
        processor1.ProcessRequest(request2);  // 输出 "Handler2 handled the request."  
    }  
}

二、java责任链模式

责任链模式通常通过以下方式实现:

// 定义一个处理者(Handler)接口  
public interface Handler {  
    void handleRequest();  
}  
  
// 定义具体处理者类1(ConcreteHandler1)  
public class ConcreteHandler1 implements Handler {  
    @Override  
    public void handleRequest() {  
        System.out.println("ConcreteHandler1 handled the request.");  
    }  
}  
  
// 定义具体处理者类2(ConcreteHandler2)  
public class ConcreteHandler2 implements Handler {  
    @Override  
    public void handleRequest() {  
        System.out.println("ConcreteHandler2 handled the request.");  
    }  
}  
  
// 定义请求类(Request)  
public class Request {  
    private String requestType;  
  
    public Request(String requestType) {  
        this.requestType = requestType;  
    }  
  
    public String getRequestType() {  
        return requestType;  
    }  
}  
  
// 定义请求处理器(RequestProcessor)类,它持有一个处理者(Handler)的引用,并调用它的handleRequest方法。如果当前处理者不能处理该请求,它将请求传递给链中的下一个处理者。  
public class RequestProcessor {  
    private Handler handler;  
  
    public RequestProcessor(Handler handler) {  
        this.handler = handler;  
    }  
  
    public void processRequest(Request request) {  
        handler.handleRequest();  
    }  
}  
  
// 测试类(Test)用于模拟客户端代码。它创建了几个处理者和请求对象,并使用请求处理器来处理请求。  
public class Test {  
    public static void main(String[] args) {  
        // 创建几个处理者对象和请求对象。注意,ConcreteHandler2 的 handleRequest 方法会在请求类型为 "Request2" 时被调用。  
        Handler handler1 = new ConcreteHandler1();  
        Handler handler2 = new ConcreteHandler2();  
        Request request1 = new Request("Request1");  
        Request request2 = new Request("Request2");  
        Request request3 = new Request("Request3");  
  
        // 使用请求处理器来处理请求。注意,每个请求处理器都可以持有一个处理者对象,并在需要时将请求传递给这个处理者对象。这种设计方式使得你可以轻松地改变请求的处理流程。  
        RequestProcessor processor1 = new RequestProcessor(handler1);  
        processor1.processRequest(request1);  // 输出 "ConcreteHandler1 handled the request."  
        processor1.processRequest(request2);  // 输出 "ConcreteHandler2 handled the request."  因为ConcreteHandler2 可以处理Request2 类型的请求. 这里因为处理器链条的设置,没有找到合适的处理器,所以会输出 "No handler can handle the request." 而不会继续传递给下一个处理器。因此,在这种情况下,处理器链条的最后一个处理器决定了处理结果。同理,对于类型为 "Request3" 的请求也没有找到合适的处理器来处理,因此输出 "No handler can handle the request."。

三、javascript责任链模式

在JavaScript中,责任链实现方式如下:

class Handler {  
  constructor() {  
    this.next = null;  
  }  
  
  handleRequest(request) {  
    if (this.canHandle(request)) {  
      console.log(`${this.name} handled request ${request}`);  
      return true;  
    } else if (this.next) {  
      return this.next.handleRequest(request);  
    } else {  
      console.log('No handler found for request');  
      return false;  
    }  
  }  
  
  canHandle(request) {  
    return false;  
  }  
}  
  
class HandlerA extends Handler {  
  constructor() {  
    super();  
    this.name = 'HandlerA';  
  }  
  
  canHandle(request) {  
    return request.type === 'A';  
  }  
}  
  
class HandlerB extends Handler {  
  constructor() {  
    super();  
    this.name = 'HandlerB';  
  }  
  
  canHandle(request) {  
    return request.type === 'B';  
  }  
}  
  
class HandlerC extends Handler {  
  constructor() {  
    super();  
    this.name = 'HandlerC';  
  }  
  
  canHandle(request) {  
    return request.type === 'C';  
  }  
}
//使用示例:
const handlerA = new HandlerA();  
const handlerB = new HandlerB();  
const handlerC = new HandlerC();  
handlerA.next = handlerB; handlerB.next = handlerC;   
handlerA.handleRequest({ type: 'A' }); // Output: HandlerA handled request A   
handlerA.handleRequest({ type: 'B' }); // Output: HandlerA handled request B   
handlerA.handleRequest({ type: 'C' }); // Output: HandlerA handled request C   
handlerA.handleRequest({ type: 'D' }); // Output: No handler found for request

四、C++责任链模式

以下是在C++中实现责任链模式:

#include <iostream>  
using namespace std;  
  
// 定义责任链中的节点类  
class Handler {  
public:  
    virtual bool canHandle(int request) = 0;  
    virtual void handleRequest(int request) = 0;  
};  
  
// 定义具体的处理器类  
class HandlerA : public Handler {  
public:  
    bool canHandle(int request) {  
        return request >= 1 && request <= 5;  
    }  
    void handleRequest(int request) {  
        cout << "HandlerA handles request: " << request << endl;  
    }  
};  
  
class HandlerB : public Handler {  
public:  
    bool canHandle(int request) {  
        return request > 5 && request <= 10;  
    }  
    void handleRequest(int request) {  
        cout << "HandlerB handles request: " << request << endl;  
    }  
};  
  
class HandlerC : public Handler {  
public:  
    bool canHandle(int request) {  
        return request > 10 && request <= 15;  
    }  
    void handleRequest(int request) {  
        cout << "HandlerC handles request: " << request << endl;  
    }  
};  
  
// 定义责任链类,负责将请求传递给合适的处理器节点进行处理  
class ResponsibilityChain {  
private:  
    Handler* head;  
public:  
    ResponsibilityChain(Handler* handler) {  
        head = handler;  
    }  
    void processRequest(int request) {  
        Handler* currentHandler = head;  
        while (currentHandler != nullptr) {  
            if (currentHandler->canHandle(request)) {  
                currentHandler->handleRequest(request);  
                break;  
            } else {  
                currentHandler = currentHandler->next;  
            }  
        }  
    }  
};  
  
int main() {  
    // 创建责任链对象,并将处理器节点按顺序链接起来形成责任链  
    ResponsibilityChain chain(new HandlerA());  
    chain.processRequest(3); // HandlerA handles request: 3 输出:3的处理由HandlerA完成。
    

五、python责任链模式

以下是在python中实现责任链模式:

class Handler:  
    def __init__(self):  
        self.next = None  
      
    def handle_request(self, request):  
        if self.can_handle(request):  
            print(f"{self.__class__.__name__} handles request: {request}")  
            return True  
        elif self.next:  
            return self.next.handle_request(request)  
        else:  
            print("No handler found for request")  
            return False  
      
    def can_handle(self, request):  
        return False  
  
class ConcreteHandlerA(Handler):  
    def can_handle(self, request):  
        return request <= 5  
  
class ConcreteHandlerB(Handler):  
    def can_handle(self, request):  
        return request > 5 and request <= 10  
  
class ConcreteHandlerC(Handler):  
    def can_handle(self, request):  
        return request > 10 and request <= 15  
  
def main():  
    handlerA = ConcreteHandlerA()  
    handlerB = ConcreteHandlerB()  
    handlerC = ConcreteHandlerC()  
    handlerA.next = handlerB  
    handlerB.next = handlerC  
      
    handlerA.handle_request(3) # Output: ConcreteHandlerA handles request: 3  
    handlerA.handle_request(6) # Output: ConcreteHandlerB handles request: 6  
    handlerA.handle_request(12) # Output: ConcreteHandlerC handles request: 12  
    handlerA.handle_request(18) # Output: No handler found for request  
  
if __name__ == "__main__":  
    main()

六、go责任链模式

以下是一个示例,展示了如何在go中实现责任链模式:

package main  
  
import "fmt"  
  
type Handler interface {  
 HandleRequest() bool  
}  
  
type ConcreteHandlerA struct{}  
  
func (h ConcreteHandlerA) HandleRequest() bool {  
 fmt.Println("ConcreteHandlerA handles request")  
 return true  
}  
  
type ConcreteHandlerB struct{}  
  
func (h ConcreteHandlerB) HandleRequest() bool {  
 fmt.Println("ConcreteHandlerB handles request")  
 return true  
}  
  
type ConcreteHandlerC struct{}  
  
func (h ConcreteHandlerC) HandleRequest() bool {  
 fmt.Println("ConcreteHandlerC handles request")  
 return true  
}  
  
func main() {  
 handlerA := ConcreteHandlerA{}  
 handlerB := ConcreteHandlerB{}  
 handlerC := ConcreteHandlerC{}  
   
 handlerA.HandleRequest() // Output: ConcreteHandlerA handles request  
 handlerB.HandleRequest() // Output: ConcreteHandlerB handles request  
 handlerC.HandleRequest() // Output: ConcreteHandlerC handles request  
}

七、PHP责任链模式

以下是一个示例,展示了如何在PHP中实现责任链模式:

<?php  
  
interface HandlerInterface {  
    public function handleRequest($request);  
}  
  
class ConcreteHandlerA implements HandlerInterface {  
    private $nextHandler;  
      
    public function __construct(HandlerInterface $nextHandler) {  
        $this->nextHandler = $nextHandler;  
    }  
      
    public function handleRequest($request) {  
        if ($request <= 5) {  
            echo "ConcreteHandlerA handles request: $request\n";  
            return true;  
        } elseif ($this->nextHandler) {  
            return $this->nextHandler->handleRequest($request);  
        } else {  
            echo "No handler found for request\n";  
            return false;  
        }  
    }  
}  
  
class ConcreteHandlerB implements HandlerInterface {  
    private $nextHandler;  
      
    public function __construct(HandlerInterface $nextHandler) {  
        $this->nextHandler = $nextHandler;  
    }  
      
    public function handleRequest($request) {  
        if ($request > 5 && $request <= 10) {  
            echo "ConcreteHandlerB handles request: $request\n";  
            return true;  
        } elseif ($this->nextHandler) {  
            return $this->nextHandler->handleRequest($request);  
        } else {  
            echo "No handler found for request\n";  
            return false;  
        }  
    }  
}  
  
class ConcreteHandlerC implements HandlerInterface {  
    private $nextHandler;  
      
    public function __construct(HandlerInterface $nextHandler) {  
        $this->nextHandler = $nextHandler;  
    }  
      
    public function handleRequest($request) {  
        if ($request > 10 && $request <= 15) {  
            echo "ConcreteHandlerC handles request: $request\n";  
            return true;  
        } elseif ($this->nextHandler) {  
            return $this->nextHandler->handleRequest($request);  
        } else {  
            echo "No handler found for request\n";  
            return false;  
        }  
    }  
}  
  
$handlerA = new ConcreteHandlerA(new ConcreteHandlerB(new ConcreteHandlerC()));  
$handlerA->handleRequest(3); // Output: ConcreteHandlerA handles request: 3  
$handlerA->handleRequest(6); // Output: ConcreteHandlerB handles request: 6  
$handlerA->handleRequest(12); // Output: ConcreteHandlerC handles request: 12  
$handlerA->handleRequest(18); // Output: No handler found for request  

?>


《完结》
上一篇《享元模式》                                                                              下一篇《解释器模式》

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1148419.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

腾讯云轻量应用服务器地域怎么选择比较好?

腾讯云轻量应用服务器地域怎么选比较好?腾讯云轻量应用服务器地域是指轻量服务器数据中心所在的地理位置&#xff0c;如上海、广州和北京等地域&#xff0c;如何选择地域&#xff1f;腾讯云百科txybk.com关于地域的选择建议就近原则&#xff0c;用户距离轻量服务器地域越近&am…

物联网AI MicroPython传感器学习 之 mpu6050六轴陀螺仪传感器

学物联网&#xff0c;来万物简单IoT物联网&#xff01;&#xff01; 一、产品简介 MPU6050是一款6轴运动传感器&#xff0c;它集成了3 轴MEMS 陀螺仪&#xff0c;3 轴MEMS加速度计&#xff0c;以及一个可扩展的数字运动处理器DMP&#xff08;Digital Motion Processor&#xf…

“破解我!“---160个CrackMe练习001-Acid buen.exe

文章目录 前言题目分析破解过程Serial/Name验证方式爆破注册机 追码 Serial验证 前言 想开个系列&#xff0c;160个Crackme的练习&#xff0c;这个在52pojie上有个精华帖总结&#xff0c;写的特别好&#xff0c;推荐&#xff01;写这个系列主要还是记录一下自己的学习记录&…

Apollo模块:开源配置管理的明日之星

Apollo模块 概述目录结构功能模块编译福利活动 主页传送门&#xff1a;&#x1f4c0; 传送 概述 目录结构 按照功能模块划分&#xff1a; |-cyber 消息中间件&#xff0c;替换ros作为消息层 |-docker 容器相关 |-docs 文档相关 |-modules 自动驾驶模块&#xff0c;主要的定位…

Android 主题 vs 样式

关于作者&#xff1a;CSDN内容合伙人、技术专家&#xff0c; 从零开始做日活千万级APP。 专注于分享各领域原创系列文章 &#xff0c;擅长java后端、移动开发、商业变现、人工智能等&#xff0c;希望大家多多支持。 目录 一、导读二、概览三、相关知识3.1 theme&#xff01; st…

YUV的红蓝颠倒(反色)的原因及解决

原因 UV排列反了。 比如说&#xff0c;NV21和YUV420SP的Y排列相同&#xff0c;UV则相反。给你YUV420SP&#xff0c;你当作NV21保存JPG&#xff0c;就会发生红蓝拿起。 解决办法 就是把UV互换一下。具体代码&#xff1a; NV21转YUV420SP的代码_nv21转yuv420格式-CSDN博客 …

[毕设记录]@开题调研:一些产品

我感觉产品能代表落地的一些实际应用&#xff0c;会和研究的角度有些差别&#xff0c;但是需求和兴趣往往是从现实中来的&#xff0c;在上一篇blog里面看外国blog的时候顺着搜搜到了很多国外的智慧校园chatbot解决方案 文章目录 Comm100streebomodern campusUniBuddy Comm100 …

git建仓库小记

git建仓库小记 1.新建远端git仓库2.新建本地仓库3.添加ssh key4.将本地仓库关联到远端5.push & pull 每次新建git项目的时候都要翻翻之前收藏的几篇帖子&#xff0c;索性自己汇总一下记录&#xff0c;以后一次粘贴搞定。 1.新建远端git仓库 这个比较简单&#xff0c;网页…

Rust编程基础之变量与可变性

1.Rust变量 在Rust语言中, 变量默认是不可改变的(immutable), 这是Rust提供给我们的众多优势之一, 让我们可以充分利用Rust提供的安全性和简单并发性来编写代码。 当变量不可变时, 一旦值被绑定在一个名称上, 就不能改变这个值。下面是一段代码的例子: fn main() {let x 1;…

vue3-访问本地json文件

将json文件放在public文件夹中 用fetch可以直接访问public下的文件 fetch(/tab-3-data/costOverhaul.json).then(response > response.json()).then(res > {console.log(res)//数据});

[云原生1.] Docker--harbor私有仓库部署与管理

文章目录 1. Harbor概述1.1 什么是Harbor1.2 Harbor的组织构成1.2.1 Proxy1.2.2 Registry1.2.3 Core services1.2.4 Database&#xff08;harbor-db&#xff09;1.2.5 Job services1.2.6 Log collector&#xff08;harbor-log&#xff09; 1.3 Harbor的特点 2. 部署Harbor服务2…

基于SSM的会员卡管理系统设计与实现

末尾获取源码 开发语言&#xff1a;Java Java开发工具&#xff1a;JDK1.8 后端框架&#xff1a;SSM 前端&#xff1a;采用JSP技术开发 数据库&#xff1a;MySQL5.7和Navicat管理工具结合 服务器&#xff1a;Tomcat8.5 开发软件&#xff1a;IDEA / Eclipse 是否Maven项目&#x…

2022年06月 Python(二级)真题解析#中国电子学会#全国青少年软件编程等级考试

Python等级考试&#xff08;1~6级&#xff09;全部真题・点这里 一、单选题&#xff08;共25题&#xff0c;每题2分&#xff0c;共50分&#xff09; 第1题 运行下列程序&#xff0c;输出的结果是&#xff1f;&#xff08; &#xff09; tup1 (苏炳添, 谷爱凌, 北京冬奥会, …

【linux】麒麟v10安装openjdk8

openjdk的官网 点我就到官网 jdk8的网址 安装 yum install -y java-1.8.0-openjdk-devel 出现Complete! 就是安装完成。 验证 java -version配置环境变量 查找安装路径 find / -name java 修改配置文件 vim /etc/profile 增加内容 export JAVA_HOME/usr/lib/jvm/j…

java项目之驾校预约管理系统(ssm框架)

项目简介 校预约管理系统实现了以下功能&#xff1a; 管理员&#xff1a;首页、个人中心、学员管理、驾校教练管理、驾校车辆管理、预约管理、取消预约管理、驾校公告管理、系统管理。驾校教练&#xff1a;首页、个人中心、驾校教练管理、预约管理、取消预约管理。学员&#…

YUV编码格式解析

YUV 颜色编码 YUV 颜色编码采用的是 明亮度 和 色度 来指定像素的颜色。 其中&#xff0c;Y 表示明亮度&#xff08;Luminance、Luma&#xff09;&#xff0c;而 U 和 V 表示色度&#xff08;Chrominance、Chroma&#xff09;。 而色度又定义了颜色的两个方面&#xff1a;色…

【Go入门】GO语言基础快速入门

Go基础 这小节我们将要介绍如何定义变量、常量、Go内置类型以及Go程序设计中的一些技巧。 定义变量 Go语言里面定义变量有多种方式。 使用var关键字是Go最基本的定义变量方式&#xff0c;与C语言不同的是Go把变量类型放在变量名后面&#xff1a; //定义一个名称为“variabl…

2023年腾讯云服务器地域节点选择指南(亲自整理)

腾讯云轻量应用服务器地域是指轻量服务器数据中心所在的地理位置&#xff0c;如上海、广州和北京等地域&#xff0c;如何选择地域&#xff1f;腾讯云百科txybk.com建议地域选择遵循就近原则&#xff0c;用户距离轻量服务器地域越近&#xff0c;网络延迟越低&#xff0c;速度就越…

从0到1之微信小程序快速入门(02)

目录 页面导航 - 声明式导航 1. 导航到 tabBar 页面 2. 导航到非 tabBar 页面 3. 后退导航 ​编辑 页面导航 - 编程式导航 页面导航 - 导航传参 页面事件 - 下拉刷新事件 监听下拉刷新事件 停止下拉刷新的效果 页面事件 - 上拉触底事件 监听页面的上拉触底事件 配置…

python实战项目基于Django的高校大学生宿舍管理系统 寝室维修保修管理系统(源码调试 开题报告lw ppt)

&#x1f495;&#x1f495;作者&#xff1a;计算机源码社 &#x1f495;&#x1f495;个人简介&#xff1a;本人七年开发经验&#xff0c;擅长Java、Python、PHP、.NET、微信小程序、爬虫、大数据等&#xff0c;大家有这一块的问题可以一起交流&#xff01; &#x1f495;&…