框架拦截器的秘密:责任链模式全解析!
引言
在移动端开发中,网络请求、UI事件分发、日志处理、安全校验等场景都离不开“过滤器(Filter)”或“拦截器(Interceptor)”。无论你是 Swift 还是 Kotlin 开发者,肯定都遇到过这样的需求:在网络请求发出前后、界面跳转前后,进行一系列可插拔、可扩展的逻辑处理。你有没有想过,这背后的核心设计思想其实就是——职责链模式(Chain of Responsibility)。
本篇我们就从移动端开发的实际视角,拆解职责链模式如何优雅支撑过滤器/拦截器框架,手把手讲清背后的原理与实战落地方案。
一、什么是职责链模式?再次回顾
职责链模式的核心思想:将一系列“处理器”串成一条链,每个处理器只关心自己职责范围内的事,其余的自动交给链上的下一个节点。这让业务流程变得灵活可扩展——你可以随时添加、删除、调整处理器的顺序,而不用大动主流程。
二、过滤器/拦截器:在移动端开发中的实际场景
- 1. 网络请求拦截(最常见)o 比如使用 Alamofire (iOS) 或 OkHttp (Android),都支持添加多个拦截器。o 可以做请求签名、鉴权、打印日志、缓存、重试等,每个功能就是一个拦截器。o 处理顺序可调,代码独立,业务高度解耦。
- 2. UI 事件处理o 比如表单校验,输入后多步校验,每步都可独立抽象为过滤器。o 比如点击防抖、权限校验、导航前拦截等。
- 3. 日志与埋点收集o 不同维度日志写到不同文件/系统,每个日志策略就是链上的一个处理器。
- 4. 数据校验与转换o 上传前做格式转换、数据加密、内容脱敏等,每步独立处理。
三、经典实现结构
1. 责任链核心接口
Swift
protocol Handler {
var next: Handler? { get set }
func handle(request: Request)
}
Kotlin
interface Handler {
var next: Handler?
fun handle(request: Request)
}
2. 具体拦截器/过滤器
Swift
class AuthHandler: Handler {
var next: Handler?
func handle(request: Request) {
if request.needsAuth {
print("进行鉴权处理")
// ...鉴权逻辑...
}
next?.handle(request: request)
}
}
class LogHandler: Handler {
var next: Handler?
func handle(request: Request) {
print("打印请求日志")
next?.handle(request: request)
}
}
Kotlin
class AuthHandler : Handler {
override var next: Handler? = null
override fun handle(request: Request) {
if (request.needsAuth) {
println("进行鉴权处理")
// ...鉴权逻辑...
}
next?.handle(request)
}
}
class LogHandler : Handler {
override var next: Handler? = null
override fun handle(request: Request) {
println("打印请求日志")
next?.handle(request)
}
}
3. 构建责任链
Swift
let logHandler = LogHandler()
let authHandler = AuthHandler()
logHandler.next = authHandler
let chainHead: Handler = logHandler
chainHead.handle(request: request)
Kotlin
val logHandler = LogHandler()
val authHandler = AuthHandler()
logHandler.next = authHandler
val chainHead: Handler = logHandler
chainHead.handle(request)
你还可以用数组+工厂模式动态拼接责任链,让插拔和顺序变得更灵活。
四、移动端主流框架的链式拦截器/过滤器实践
1. iOS 网络层:Alamofire 的 Interceptor
Alamofire 支持链式 RequestInterceptor。你可以组合多种拦截器,每个拦截器负责独立的处理逻辑:
class CustomRequestInterceptor: RequestInterceptor {
private let interceptors: [RequestInterceptor]
init(interceptors: [RequestInterceptor]) {
self.interceptors = interceptors
}
func adapt(_ urlRequest: URLRequest, for session: Session, completion: @escaping (Result<URLRequest, Error>) -> Void) {
// 遍历所有拦截器,依次处理
}
}
2. Android 网络层:OkHttp 的 Interceptor
OkHttp 拦截器链就是典型的职责链实现。每个拦截器独立处理,最后决定是否继续调用链上的下一个。
class AuthInterceptor : Interceptor {
override fun intercept(chain: Interceptor.Chain): Response {
// 做鉴权
val request = chain.request().newBuilder()
// ...添加Header等
.build()
return chain.proceed(request)
}
}
开发者可以动态组合多个 Interceptor,实现请求加密、重试、日志、Mock 等功能,顺序可配。
五、进阶:职责链+异步处理
移动端的责任链往往需要支持异步操作,例如网络请求前的 Token 刷新、数据加密、UI 主线程切换等。
Swift 中的异步链
protocol AsyncHandler {
var next: AsyncHandler? { get set }
func handle(request: Request, completion: @escaping (Result<Response, Error>) -> Void)
}
每个 Handler 执行完毕后回调 completion,再触发下一个 Handler,直到链尾。
Kotlin 的挂起(suspend)链式实现
interface SuspendHandler {
var next: SuspendHandler?
suspend fun handle(request: Request): Response
}
通过协程串联,既高效又可控。
六、优缺点与实战建议
优点
- o 高度解耦:每个处理器专注于单一职责,代码易于维护和扩展。
- o 灵活可插拔:新功能直接新增 Handler/Interceptor,无需大改主流程。
- o 顺序可控:开发者可通过配置或代码动态调整责任链顺序。
- o 易于单测:每个 Handler 可独立测试,避免联动出错。
缺点
- o 链路过长可能有性能损耗,尤其在高频场景需注意链路长度。
- o Debug 难度稍高,出现问题时需逐步排查链路中的各节点。
实战建议
- o 通用逻辑(如日志、埋点、权限等)一定要抽离为责任链节点,不要硬编码在主流程中。
- o 责任链适合“流程可裁剪、处理可分段”的业务场景,不适合强依赖顺序、强耦合业务。
- o 异步链要注意线程安全、内存释放等问题,避免回调地狱或协程泄露。
七、观点升华
职责链模式让移动端 App 的“过滤、拦截、扩展”能力变得极为强大。
无论是网络请求还是 UI 事件,职责链都能让我们优雅地组合功能,既保证了灵活性,又提升了架构的弹性。未来复杂的业务流程,建议更多地用链式思想来解耦,让代码更可维护、更可迭代。