在上一篇文章《观察者模式:让代码主动响应,告别轮询》中,我们探讨了观察者模式如何以解耦的方式实现系统事件响应。作为行为设计模式系列的第二篇,本文将介绍另一种行为模式——责任链模式(Chain of Responsibility)。顾名思义,该模式会为请求创建一条由多个潜在处理器组成的链条。请求会沿着这条链条依次传递,直到某个处理器能够处理它为止。这种方式将请求的发送者与接收者解耦,从而提升代码设计的灵活性和整洁度。
责任链模式(简称CoR,又称“命令链”模式)能有效避免请求发送者与接收者之间的紧耦合。与观察者模式类似,CoR是一种关注对象间通信与行为组织的行为模式。但观察者模式是向多个监听者广播消息,而责任链模式则是让消息依次通过处理器管道传递。下面我们将深入解析CoR的核心思想、适用场景及实现方式(附Kotlin示例)。
定义:责任链是一种设计模式,请求会沿着处理器链依次传递,直到某个处理器处理该请求。链中的每个处理器都有机会处理请求或将其传递给下一个处理器。客户端(发起请求的代码)无需关心最终由哪个处理器处理请求——只需将请求发送到链中即可。这种方式遵循开闭原则,允许新增处理器而无需修改现有代码。
简而言之,CoR将一系列条件判断转化为灵活的面向对象结构。它是传统if-else if-else
或switch
语句的面向对象替代方案。请求的处理路径由链条结构动态决定,而非发送者显式指定。这使得代码更易扩展——即使运行时也能调整或新增处理器,而无需修改请求分发逻辑。
运作原理:
Handle(request)
方法和指向下一个处理器的引用。假设你身体不适需要就医:
类比映射:
关键点在于:患者无需预先知道哪位医生能解决问题,只需从第一个接触点开始,由链条动态路由。这避免了患者自行判断“如果是心脏问题去A科室,如果是耳朵问题去B科室……”的复杂性。
if-else
链。典型场景:
(以下为Kotlin代码,保留原格式与注释)
// 处理器接口
interface SupportHandler {
fun handleRequest(issue: SupportIssue)
}
// 支持问题数据类
data class SupportIssue(val description: String, val complexity: Int)
// 抽象基类实现链逻辑
abstract class AbstractSupportHandler(private val next: SupportHandler? = null) : SupportHandler {
abstract fun canHandle(issue: SupportIssue): Boolean
abstract fun doHandle(issue: SupportIssue)
override fun handleRequest(issue: SupportIssue) {
if (canHandle(issue)) {
doHandle(issue)
} else {
next?.handleRequest(issue) ?: println("Issue '${issue.description}'未被处理")
}
}
}
// 具体处理器:一线支持
class Tier1Support(next: SupportHandler? = null) : AbstractSupportHandler(next) {
override fun canHandle(issue: SupportIssue) = issue.complexity <= 1
override fun doHandle(issue: SupportIssue) {
println("Tier1Support处理问题:${issue.description}")
}
}
// 使用示例
fun main() {
val chain = Tier1Support(Tier2Support(Tier3Support()))
chain.handleRequest(SupportIssue("密码重置", 1)) // Tier1处理
chain.handleRequest(SupportIssue("数据库崩溃", 3)) // Tier3处理
}
责任链模式通过将请求委托给处理器链,有效替代硬编码的条件逻辑。它遵循开闭原则和单一职责原则,适用于多处理器动态协作的场景。但需警惕过度使用——并非所有if-else
都需要升级为责任链。
“责任链就像流水线:每个工位只做自己该做的事,做不了就交给下一位。”
你是否在项目中使用过该模式?欢迎分享经验或转发给正在if-else
苦海中挣扎的队友!