元素码农
基础
UML建模
数据结构
算法
设计模式
网络
TCP/IP协议
HTTPS安全机制
WebSocket实时通信
数据库
sqlite
postgresql
clickhouse
后端
rust
go
java
php
mysql
redis
mongodb
etcd
nats
zincsearch
前端
浏览器
javascript
typescript
vue3
react
游戏
unity
unreal
C++
C#
Lua
App
android
ios
flutter
react-native
安全
Web安全
测试
软件测试
自动化测试 - Playwright
人工智能
Python
langChain
langGraph
运维
linux
docker
工具
git
svn
🌞
🌙
目录
▶
设计原则
单一职责原则
开闭原则
里氏替换原则
依赖倒置原则
接口隔离原则
迪米特法则
▶
创建型模式
工厂方法模式
抽象工厂
单例模式
建造者模式
原型模式
▶
结构型模式
适配器模式
装饰器模式
代理模式
外观模式
组合模式
桥接模式
享元模式
▶
行为型模式
策略模式
观察者模式
命令模式
模板方法模式
状态模式
责任链模式
迭代器模式
中介者模式
访问者模式
备忘录模式
解释器模式
发布时间:
2025-03-21 15:22
↑
☰
# 责任链模式 ## 概述 责任链模式(Chain of Responsibility Pattern)是一种行为型设计模式,它允许你将请求沿着处理者链进行发送。收到请求后,每个处理者均可对请求进行处理,或将其传递给链上的下个处理者。 ## 问题场景 在软件开发中,我们经常会遇到以下场景: 1. 需要多个对象可以处理同一个请求 2. 不明确接收者的情况下向多个对象中的某一个提交请求 3. 处理者集合需要动态指定 ## 解决方案 责任链模式通过以下方式解决这些问题: ```mermaid classDiagram class Handler { <<interface>> +setNext(Handler) +handle(request) -next: Handler } class ConcreteHandlerA { +handle(request) } class ConcreteHandlerB { +handle(request) } class ConcreteHandlerC { +handle(request) } Handler <|.. ConcreteHandlerA Handler <|.. ConcreteHandlerB Handler <|.. ConcreteHandlerC Handler o-- Handler ``` 主要角色: 1. 处理者(Handler): 定义处理请求的接口,实现后继链 2. 具体处理者(ConcreteHandler): 处理请求,可以访问后继者 ## 代码示例 ### 1. 基本实现 ```go // Handler 处理者接口 type Handler interface { SetNext(handler Handler) Handler Handle(request string) string } // BaseHandler 基础处理者 type BaseHandler struct { next Handler } func (h *BaseHandler) SetNext(handler Handler) Handler { h.next = handler return handler } func (h *BaseHandler) Handle(request string) string { if h.next != nil { return h.next.Handle(request) } return "" } // ConcreteHandlerA 具体处理者A type ConcreteHandlerA struct { BaseHandler } func (h *ConcreteHandlerA) Handle(request string) string { if request == "A" { return "Handler A handled the request" } return h.BaseHandler.Handle(request) } // ConcreteHandlerB 具体处理者B type ConcreteHandlerB struct { BaseHandler } func (h *ConcreteHandlerB) Handle(request string) string { if request == "B" { return "Handler B handled the request" } return h.BaseHandler.Handle(request) } ``` ### 2. 实际应用示例 ```go // 以日志处理为例 // LogLevel 日志级别 type LogLevel int const ( INFO LogLevel = iota DEBUG ERROR ) // LogEntry 日志条目 type LogEntry struct { level LogLevel message string } // LogHandler 日志处理者接口 type LogHandler interface { SetNext(handler LogHandler) LogHandler Log(entry LogEntry) string } // BaseLogHandler 基础日志处理者 type BaseLogHandler struct { next LogHandler } func (h *BaseLogHandler) SetNext(handler LogHandler) LogHandler { h.next = handler return handler } func (h *BaseLogHandler) Log(entry LogEntry) string { if h.next != nil { return h.next.Log(entry) } return "" } // InfoLogHandler 信息日志处理者 type InfoLogHandler struct { BaseLogHandler } func (h *InfoLogHandler) Log(entry LogEntry) string { if entry.level == INFO { return fmt.Sprintf("[INFO] %s", entry.message) } return h.BaseLogHandler.Log(entry) } // DebugLogHandler 调试日志处理者 type DebugLogHandler struct { BaseLogHandler } func (h *DebugLogHandler) Log(entry LogEntry) string { if entry.level == DEBUG { return fmt.Sprintf("[DEBUG] %s", entry.message) } return h.BaseLogHandler.Log(entry) } // ErrorLogHandler 错误日志处理者 type ErrorLogHandler struct { BaseLogHandler } func (h *ErrorLogHandler) Log(entry LogEntry) string { if entry.level == ERROR { return fmt.Sprintf("[ERROR] %s", entry.message) } return h.BaseLogHandler.Log(entry) } // Logger 日志记录器 type Logger struct { handler LogHandler } func NewLogger() *Logger { // 创建处理链 infoHandler := &InfoLogHandler{} debugHandler := &DebugLogHandler{} errorHandler := &ErrorLogHandler{} infoHandler.SetNext(debugHandler).SetNext(errorHandler) return &Logger{handler: infoHandler} } func (l *Logger) Log(level LogLevel, message string) string { return l.handler.Log(LogEntry{level: level, message: message}) } // 使用示例 func main() { logger := NewLogger() fmt.Println(logger.Log(INFO, "This is an information message")) fmt.Println(logger.Log(DEBUG, "This is a debug message")) fmt.Println(logger.Log(ERROR, "This is an error message")) } ``` ## 适用场景 1. 多个对象可以处理请求 - 在不明确接收者的情况下,向多个对象中的某一个提交请求 - 可处理一个请求的对象集合应被动态指定 2. 请求的处理有顺序要求 - 请求需要按特定顺序经过多个处理者 - 处理者的执行顺序事先已知 3. 责任链的动态性 - 责任链可以动态改变 - 处理者的链接关系可以在运行时改变 ## 优缺点 ### 优点 1. 降低耦合度 - 发送者和接收者解耦 - 处理者之间解耦 2. 增加灵活性 - 动态改变责任链 - 动态新增或删除处理者 3. 符合单一职责原则 - 每个处理者只负责自己的处理逻辑 - 各司其职,互不干扰 ### 缺点 1. 请求可能无人处理 - 链尾没有处理者 - 没有合适的处理者 2. 系统性能问题 - 请求可能遍历整个链 - 处理时间不确定 ## 实现要点 1. 处理者接口设计 - 定义处理请求的方法 - 定义设置后继者的方法 2. 链的组装 - 确定处理顺序 - 正确设置后继者 3. 请求传递 - 处理或转发请求 - 避免请求丢失 ## 相关模式 1. 组合模式 - 责任链的处理者可以组合 - 形成树形结构 2. 命令模式 - 责任链可以与命令模式结合 - 处理命令对象 3. 装饰器模式 - 责任链类似于装饰器链 - 都是对对象的包装 ## 总结 责任链模式是一种用于处理请求的行为型设计模式,它的核心价值在于: 1. 解耦 - 将请求的发送者和接收者解耦 - 使系统更加灵活 2. 动态性 - 可以动态组织处理者 - 灵活调整处理逻辑 3. 责任分配 - 明确每个处理者的职责 - 简化请求的处理流程 在实际开发中,责任链模式常用于处理复杂的请求流程,如日志处理、权限验证、过滤器等场景。使用时需要注意处理者的顺序和请求的完整性,确保请求能够得到正确处理。