当前位置: 首页 > news >正文

设计模式笔记_行为型_责任链模式

1. 责任链模式介绍

责任链模式(Chain of Responsibility)是一种行为设计模式,它允许将多个处理器(处理对象)连接成一条链,并沿着这条链传递请求,直到有一个处理器处理它为止。职责链模式的主要目的是避免请求的发送者与多个请求处理者之间的耦合。

类比场景:想象一下,客户服务中心有多个层级的客服人员:初级客服、高级客服和经理。客户的问题会从初级客服开始,逐级向上转发,直到有一个客服能够解决问题。

组成结构:职责链模式主要包含以下几个部分:

  1. 抽象处理者(Handler):定义一个处理请求的接口,并包含一个指向下一个处理者的引用。
  2. 具体处理者(ConcreteHandler):实现处理请求的具体逻辑,并决定是否将请求传递给下一个处理者。
  3. 处理器链(HandlerChain): 在职责链模式的实现中,使用HandlerChain不是必须的,但是一种常见的做法。HandlerChain 的使用主要是为了简化链的管理,使得链的创建和维护更加便捷和集中。
  4. 客户端(Client):负责创建处理链,并向链中的第一个处理者发送请求。

优缺点分析:

  • 优点
    • 降低耦合:请求发送者和接收者之间的耦合度降低,灵活地新增和修改处理者。
    • 动态组合:可以方便地改变链内的成员或调动它们的次序。
  • 缺点
    • 不保证请求被处理:如果链的末端没有处理请求,可能会导致请求不被处理。这个场景可以通过责任链的变体实现,让请求被所有处理器都处理。
    • 性能问题:链过长可能导致性能问题,因为请求需要经过多个处理者。

适用场景:

  • 需要动态地指定请求的处理者。
  • 有多个对象可以处理某个请求,但具体处理者不确定。
  • 希望请求的发送者和接收者解耦。

2. 代码演示

责任链有链表列表两种实现方式,这里分别演示。演示场景围绕“初级客服、高级客服和经理处理客诉”展开。

2.1 链表实现

抽象处理者(Handler):链式实现方式中,抽象处理类是一个抽象类,里面定义了处理请求的接口(这里是doHandle接口),并包含指向下一个处理者的引用(这里对应nextHandler属性)。通常还会将调用下个处理器的通用逻辑提取出来(对应handleRequest方法),这样具体处理器类只需要实现自己的业务逻辑就可以了。

// 抽象处理者
public abstract class CustomerServiceHandler {//下一个处理器的对象protected CustomerServiceHandler nextHandler;public void setNextHandler(CustomerServiceHandler nextHandler) {this.nextHandler = nextHandler;}//调用下个处理器的逻辑,原本放在具体处理器中;属于通用逻辑,这里利用模版模式提取到父类public void handleRequest(String request) {boolean handled = doHandle(request);//gof定义:若当前处理器不能处理,则需要向下个处理器传递; 否则结束if (!handled && nextHandler != null) {nextHandler.handleRequest(request);}}//抽象处理逻辑:具体实现放在各handler自己实现的  doHandle() 函数里public abstract boolean doHandle(String request);}

具体处理者(ConcreteHandler):

//具体处理者 - 初级客服
public class JuniorCustomerService extends CustomerServiceHandler {@Overridepublic boolean doHandle(String request) {if (request.equals("basic")) {System.out.println("junior customer service handle");return true;}return false;}
}// 具体处理者 - 高级客服
public class SeniorCustomerService extends CustomerServiceHandler {@Overridepublic boolean doHandle(String request) {if (request.equals("advanced")) {System.out.println("senior customer service handle");return true;}return false;}
}// 具体处理者 - 经理
public class Manager extends CustomerServiceHandler {@Overridepublic boolean doHandle(String request) {if (request.equals("complex")) {System.out.println("manager customer service handle");return true;}return false;}
}

处理器链(HandlerChain):HandlerChain不是必须的,在某些情况下,直接在客户端代码中构建职责链是足够的,尤其是链简单且变化不频繁的时候。然而,在处理复杂链或需要动态调整链的场景下,引入 HandlerChain 可以提高代码的清晰度和灵活性。通过HandlerChain集中管理handlers,负责链中处理者的添加、移除和遍历,简化链的管理。

public class CustomerServiceHandlerChain {private CustomerServiceHandler firstHandler;private CustomerServiceHandler lastHandler;//给链表中添加处理器public void addHandler(CustomerServiceHandler handler) {if (firstHandler == null) {//链表头为null,放在链表头firstHandler = handler;lastHandler = handler;} else {//否则放在链表尾lastHandler.setNextHandler(handler);lastHandler = handler;}}//执行链表中的处理器:从第一个处理器开始执行public void handleRequest(String request) {if (null != firstHandler) {firstHandler.handleRequest(request);}}
}

客户端代码:

public class CustomerServiceChainDemo {public static void main(String[] args) {CustomerServiceHandlerChain handlerChain = new CustomerServiceHandlerChain();handlerChain.addHandler(new JuniorCustomerService());handlerChain.addHandler(new SeniorCustomerService());handlerChain.addHandler(new Manager());// 测试不同请求//handlerChain.handleRequest("basic");handlerChain.handleRequest("advanced");}
}

对应的类图:

2.2 列表实现

列表实现方式更加简单,与链表实现的差异点:

  • 抽象处理者(handler)改用interface (无需存储对下一个处理者的引用)
  • HandlerChain类中用列表而非链表来保存所有的处理器
  • 在HandlerChain中,依次调用每个handler(链表对nextHandler的调用放在抽象处理者类中)

抽象处理者(Handler):列表实现方式中,抽象处理者是一个接口,定义处理请求的方法。

//抽象处理者
public interface CustomerServiceHandler {boolean handlerRequest(String request);
}

具体处理者(ConcreteHandler):

//具体处理者 - 初级客服
public class JuniorCustomerService implements CustomerServiceHandler {@Overridepublic boolean handlerRequest(String request) {if (request.equals("basic")) {System.out.println("junior customer service handle");return true;}return false;}
}//具体处理者 - 高级客服
public class SeniorCustomerService implements CustomerServiceHandler {@Overridepublic boolean handlerRequest(String request) {if (request.equals("advanced")) {System.out.println("senior customer service handle");return true;}return false;}
}//具体处理者 - 经理
public class Manager implements CustomerServiceHandler {@Overridepublic boolean handlerRequest(String request) {if (request.equals("complex")) {System.out.println("manager customer service handle");return true;}return false;}
}

处理器链(HandlerChain):HandlerChain类中用列表而非链表来保存所有的处理器,并在HandlerChain的handle()函数中,依次调用每个处理器的handle()函数。

public class CustomerServiceHandlerChain {private List<CustomerServiceHandler> handlerList = new ArrayList<>();public void addHandler(CustomerServiceHandler handler) {handlerList.add(handler);}public void handleRequest(String request) {for (CustomerServiceHandler handler : handlerList) {//gof定义: 若当前处理器不能处理,则向下一个处理器传递; 否则结束Boolean handledResult = handler.handlerRequest(request);if (handledResult) {break;}}}
}

客户端代码:

public class CustomerServiceChainDemo {public static void main(String[] args) {CustomerServiceHandlerChain handlerChain = new CustomerServiceHandlerChain();handlerChain.addHandler(new JuniorCustomerService());handlerChain.addHandler(new SeniorCustomerService());handlerChain.addHandler(new Manager());// 测试不同请求handlerChain.handleRequest("basic");}
}

对应的类图:

2.3 变体:所有handler都处理一遍

上述实现是按照gof定义:如果处理器链上的某个处理器能够处理这个请求,那就不会继续往下传递请求,整个流程就会结束

职责链模式还有一种变体,那就是请求会被所有的处理器都处理一遍,不存在中途终止的情况。还是使用上述客服场景,假设用户需要退款,需要 初级/高级/经理 三级客服签字确认。

列表实现的代码如下:

//抽象处理者
public interface CustomerServiceHandler {void handlerRequest(String request);
}
//具体处理者 - 初级客服
public class JuniorCustomerService implements CustomerServiceHandler {@Overridepublic void handlerRequest(String request) {//doSomething ...System.out.println("junior customer service handle");}
}//具体处理者 - 高级客服
public class SeniorCustomerService implements CustomerServiceHandler {@Overridepublic void handlerRequest(String request) {//doSomething ...System.out.println("senior customer service handle");}
}//具体处理者 - 经理
public class Manager implements CustomerServiceHandler {@Overridepublic void handlerRequest(String request) {//doSomething ...System.out.println("manager customer service handle");}
}
//处理器链
public class CustomerServiceHandlerChain {private List<CustomerServiceHandler> handlerList = new ArrayList<>();public void addHandler(CustomerServiceHandler handler) {handlerList.add(handler);}public void handleRequest(String request) {for (CustomerServiceHandler handler : handlerList) {//变体类型: 不关注 handled值,请求会被所有的处理器都处理一遍,不存在中途终止的情况handler.handlerRequest(request);}}
}
//客户端代码
public class CustomerServiceChainDemo {public static void main(String[] args) {CustomerServiceHandlerChain handlerChain = new CustomerServiceHandlerChain();handlerChain.addHandler(new JuniorCustomerService());handlerChain.addHandler(new SeniorCustomerService());handlerChain.addHandler(new Manager());//发起退款handlerChain.handleRequest("退款100元");}
}

http://www.dtcms.com/a/330575.html

相关文章:

  • 【论文阅读 | CVPR 2024 | UniRGB-IR:通过适配器调优实现可见光-红外语义任务的统一框架】
  • linux 内核 - 内存管理的层次化结构
  • UE5配置MRQ编解码器输出MP4视频
  • Linux网络编程:应用层自定义协议与序列化
  • 《量子雷达》第5章 量子雷达发射机 预习2025.8.14
  • 人工智能——卷积神经网络自定义模型全流程初识
  • .NET 的 WebApi 项目必要可配置项都有哪些?
  • CPUcores-【硬核优化】CPU增强解锁全部内核!可优化游戏性能、提升帧数!启用CPU全内核+超线程,以更高优先级运行游戏!支持各种游戏和应用优化~
  • Mybatis学习笔记(四)
  • 【论文阅读】基于卷积神经网络和预提取特征的肌电信号分类
  • CSS isolation属性
  • NVIDIA Nsight Deep Learning Designer使用
  • 第3节 深度学习避坑指南:从过拟合到玄学优化
  • toRefs、storeToRefs实际应用
  • 分布式系统架构设计模式:从微服务到云原生
  • Flutter sqflite插件
  • Day57--图论--53. 寻宝(卡码网)
  • Nacos-4--Nacos1.x长轮询的理解
  • PiscTrace基于YOLO追踪算法的物体速度检测系统详解
  • 【软考中级网络工程师】知识点之入侵防御系统:筑牢网络安全防线
  • 【入门级-算法-2、入门算法:模拟法】
  • 解决“Win7共享文件夹其他电脑网络无法发现共享电脑名称”的问题
  • 融合服务器助力下的电视信息发布直播点播系统革新
  • 服务器装两个cpu
  • 1780. 判断一个数字是否可以表示成三的幂的和
  • MongoDB 从入门到生产:建模、索引、聚合、事务、分片与运维实战(含 Node.js/Python 示例)
  • 基于现代 C++ 的湍流直接数值模拟 (DNS) 并行算法优化与实现
  • 9.【C++进阶】继承
  • 河南萌新联赛2025第(五)场:信息工程大学”(补题)
  • QLab Pro for Mac —— 专业现场音频与多媒体控制软件