当前位置: 首页 > 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.lryc.cn/news/621261.html

相关文章:

  • 仓颉编程语言的Any 类型(Any 接口)
  • Video-R1论文解读
  • 使用keil5 自带的仿真观察GPIO口波形
  • lib.dom.d.ts
  • 《量子雷达》第4章 量子雷达的检测与估计 预习2025.8.14
  • Windows bypassUAC 提权技法详解(一)
  • ACCESS多个时间段查询,只取整点,30分数据
  • 【读代码】深度解析 context-engineering-intro:开源上下文工程实践原理与应用
  • 【Functions】enumerate的用法
  • 机器学习-基础入门:从概念到核心方法论
  • Data Augmentation数据增强
  • 从0到1:C++ 语法之 nullptr
  • 机器学习内容总结
  • 机器学习初学
  • 前端vue框架
  • 机器学习知识总结
  • 智能体评测技术与实践:从评估维度到DeepEval实战指南
  • 20250814,通义万相,无限生成权限(慢速)
  • Linux中的日志管理
  • Linux中tty与8250-uart的虐恋(包括双中断发送接收机制)
  • 前端包管理工具
  • hive加载csv中字段含有换行符的处理方法
  • Spring-cloud-openfeign-设置超时时间
  • 数据结构:用两个栈模拟队列(Queue Using 2 Stacks)
  • 8.14网络编程——TCP通信基础
  • 【22-决策树】
  • 零基础-动手学深度学习-10.3. 注意力评分函数
  • 20道CSS相关前端面试题及答案
  • torch.nn中Sequential的使用
  • 【代码随想录day 20】 力扣 538.把二叉搜索树转换为累加树