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

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

简介:

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

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

责任链模式的使用场景:
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.mzph.cn/news/122859.shtml

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

相关文章

word页脚设置,页脚显示第几页共有几页设置步骤

word页脚设置&#xff0c;页脚显示第几页共有几页设置步骤&#xff1a; 具体步骤&#xff1a; 步骤1&#xff1a; 步骤1.1选择页脚---空白页脚 步骤1.2&#xff0c;在"[在此处键入]"&#xff0c;直接输入你需要的格式&#xff0c;如 “第页/共页” 步骤1.3选择第“…

jmeter BeanShell预处理程序:报错JSONObject not found in namespace

1、jmeter运行报错: ERROR o.a.j.u.BeanShellInterpreter: Error invoking bsh method: eval Sourced file: inline evaluation of: ". . . : Typed variable declaration : Class: JSONObject not found in namespace WARN o.a.j.m.BeanShellPreProcessor: Problem…

AI:40-基于深度学习的森林火灾识别

🚀 本文选自专栏:AI领域专栏 从基础到实践,深入了解算法、案例和最新趋势。无论你是初学者还是经验丰富的数据科学家,通过案例和项目实践,掌握核心概念和实用技能。每篇案例都包含代码实例,详细讲解供大家学习。 📌📌📌本专栏包含以下学习方向: 机器学习、深度学…

【Java】LinkedList 集合

LinkedList集合特点 LinkedList 底层基于双向链表实现增删 效率非常高&#xff0c;查询效率非常低。 LinkedList源码解读分析 LinkedList 是双向链表实现的 ListLinkedList 是非线程安全的&#xff08;线程是不安全的&#xff09;LinkedList 元素允许为null,允许重复元素Linked…

2023版 STM32实战12 IIC总线读写AT24C02

IIC简述 一个多主从的串行总线&#xff0c;又叫I2C&#xff0c;是由飞利浦公司发明的通讯总线 IIC特点 -1- 串行(逐bit传输) -2- 同步(共用时钟线) -3- 半双工(收发不同进行) -4- 总线上的任何设备都可以是主机 开发使用习惯和理解 -1- 通过地址寻址 -2- 数据线的…

Ubuntu20.04下安装MySQL8环境

Ubuntu20.04下安装MySQL8环境 1.下载MySQL客户端和服务器2.配置MySQL3.测试MySQL4.设置MySQL服务开机自启动5.修改root密码MySQL数据库基本使用启动MySQL数据库服务重启MySQL数据库服务停止MySQL数据库服务查看MySQL运行状态设置MySQL服务开机自启动停止MySQL服务开机自启动MyS…

[Linux]线程池

[Linux]线程池 文章目录 [Linux]线程池线程池的概念线程池的优点线程池的应用场景线程池的实现 线程池的概念 线程池是一种线程使用模式。线程池是一种特殊的生产消费模型&#xff0c;用户作为生产者&#xff0c;线程池作为消费者和缓冲区。 线程过多会带来调度开销&#xff0c…

在docker中创建EMQX 加数据卷

1、从虚拟容器中复制出来文件 docker run --rm emqx/emqx:5.3.0 sh -c cd /opt/emqx && tar -c etc | tar -C $PWD -x 2、将这三个文件夹分别赋予最高权限&#xff0c;也可以777可以755 chmod -R 777 data chmod -R 777 etc chmod -R 777 log 3、创建容器代码 docke…

加解密原理(HCIA)

一、加密技术 1、加密的两个核心组件 2、加密技术作用&#xff1a; 二、加解密技术原理 1、对称加密 2、非对称加密 &#xff08;1&#xff09;思考问题&#xff1f; 1&#xff09;、有了非对称加密为什么还用对称加密&#xff1f; 2&#xff09;、如何传递秘钥呢&…

服务器动态/静态/住宅/原生IP都是什么意思

​  在互联网的世界中&#xff0c;我们经常会听到关于IP地址的各种说法&#xff0c;比如服务器动态IP、静态IP、住宅IP和原生IP。那么这些术语究竟代表着什么意思呢?让我们一起来了解一下。 动态IP 动态IP(Dynamic IP)是指互联网服务提供商(ISP)在每次用户上网时&#xff0c…

Redis中的数据类型以及适用场景

1.Redis中的数据类型 Redis中的数据类型包括&#xff1a;String(字符串&#xff09;、Hash(字典)、List(列表)、Set(集合)、Sorted Set【Zset】(有序集合&#xff09;。 Redis 所有的数据结构都是一个key对应一个value&#xff0c;不同类型的数据结构之间的差异就在于value的…

【微信小程序开发】学习小程序的网络请求和数据处理

前言 网络请求是微信小程序中获取数据和与服务器交互的重要方式。微信小程序提供了自己的API来处理网络请求&#xff0c;使得开发者可以轻松地在微信小程序中实现数据的获取和提交。本文将介绍微信小程序中的网络请求&#xff0c;包括使用wx.request发起GET和POST请求&#xf…

jenkins实践篇(1)——基于分支的自动发布

问题背景 想起初来公司时&#xff0c;我们还是在发布机上直接执行发布脚本来运行和部署服务&#xff0c;并且正式环境和测试环境的脚本都在一起&#xff0c;直接手动操作脚本时存在比较大的风险就是将环境部署错误&#xff0c;并且当时脚本部署逻辑还没有检测机制&#xff0c;…

JVM面试知识点整理

文章目录 (一) JVM组成JVM组成部分和运行流程从图中可以看出 JVM 的主要组成部分运行流程&#xff1a;程序计数器Java堆虚拟机栈方法区堆栈的区别是什么&#xff1f; (二) 类加载器双亲委派模型类装载的执行过程 (三) 垃圾回收对象什么时候可以被垃圾回收哪些可以作为根对象 垃…

【QT】Qt控件不显示图标

问题描述 本人在跟着B站视频学习QT时&#xff0c;遇到了一件十分悲惨的事情&#xff0c;一模一样的步骤&#xff0c;我的图标却不能显示。 于是我上网查询一下解决方案&#xff0c;第一种&#xff0c;亲测没用&#xff1b;第二种亲测可以。 解决方法一 1、构建 -> 清理项目…

ArcGIS Maps SDK for JS:隐藏地图边框

文章目录 1 问题描述2 解决方案 1 问题描述 近期&#xff0c;将ArcGIS Api for JS v4.16更新到了ArcGIS Maps SDK for JS v4.27&#xff0c;原本去除地图的css代码失效了。 v4.26及以前版本 &#xff0c;需要用.esri-view-surface--inset-outline:focus::after 控制边框属性。…

假如我有一台服务器,我会让它提供三种服务

一、提供照片上传、存储和下载服务 随着移动互联网时代的持续快速发展&#xff0c;PC互联网日益势微&#xff0c;各大互联网门户网站的博客、空间也跟着凋零&#xff0c; 作为博客、空间的标配功能的相册也随之被关闭。 2019年3月6日网易相册发布停运公告并于当年5月8日正式停…

基于RK3568高性价比全国产EMS储能解决方案(二)设计方案

目录 版 本 修 订 记 录 1. 产品介绍 1.1. 什么是XM3568-EP 1.2. 产品特点 1.3. 外壳尺寸 1.4. 外壳外观 1.5. 规格参数 2. 设备使用介绍 2.1. 下载需要使用到的驱动和调试工具 2.2. 启动网关 2.3. DEBUG串口的使用方法 2.4. LED指示灯说明 3. Linux系…

0029Java程序设计-家政服务平台管理系统

文章目录 摘要目录系统设计开发环境 摘要 本文首先研究并介绍国内外目前的背景和现状&#xff0c;在此基础上给出论文的主要研究内容&#xff0c;其次&#xff0c;对家政服务平台管理系统的需求进行了分析。再次&#xff0c;对家政服务平台管理系统进行了总体设计&#xff0c;…

【java学习—九】模板方法(TemplateMethod)设计模式(4)

文章目录 1. 在java中什么是模板2. 模板方法设计解决了什么问题&#xff1f;3. 代码化理解 1. 在java中什么是模板 抽象类体现的就是一种模板模式的设计&#xff0c;抽象类作为多个子类的通用模板&#xff0c;子类在抽象类的基础上进行扩展、改造&#xff0c;但子类总体上会保留…