什么是责任链模式
在构建复杂系统时,我们常常面临这样的挑战: 一个请求或事件需要经过多个处理环节 ,这些环节可能动态变化,处理者在运行时才能确定。如何优雅地组织这些处理逻辑,避免代码陷入臃肿的"巨无霸方法"困境?
想象这样的场景:系统启动初始化流程需要依次执行用户初始化、展示数据加载、元数据配置和系统 Banner 展示等步骤。如果不用设计模式,代码往往沦为这样的"一坨":
public void initSystem() { // 初始化用户模块 initUserService(); // 加载展示数据 loadDisplayData(); // 配置元数据 configureMetadata(); // 展示系统Banner showStartupBanner(); // 新增需求:添加系统监控 initMonitoring(); // 每次新增都要修改这个核心方法! // 未来可能还要添加更多步骤... }
这种实现存在三大痛点:
- 违反开闭原则 :每次新增初始化步骤都要修改
initSystem()
方法 - 耦合度高 :各步骤执行顺序硬编码在单一方法中
- 难以扩展 :无法动态调整处理流程(如跳过某些步骤)
责任链模式 (Chain of Responsibility) 正是解决这类问题的利器。它像搭建乐高积木一样,将处理步骤拆分为独立单元,通过链式连接实现灵活组装:
// 构建初始化责任链 InitializationChain chain = new InitializationChain(); chain.addHandler(new UserInitHandler()) .addHandler(new DataLoadHandler()) .addHandler(new MetadataHandler()) .addHandler(new BannerHandler()); // 执行初始化流程 chain.execute();
当需要新增监控初始化时,只需:
chain.insertAfter(MetadataHandler.class, new MonitoringHandler());
无需触碰核心逻辑 ,系统初始化流程即刻升级。甚至可以做到热拔插不用停机也能更新升级!。
和策略模式的区别
很多人会把责任链和策略模式混淆,它们确实都强调“解耦逻辑”,但关注点不同:
模式 | 适用场景 |
---|---|
策略模式 | 替代 if-else,根据条件选择一种处理方式 |
责任链模式 | 请求需要“多步处理”或“逐步接力”,处理器可能中断或放行请求传递 |
简言之:
- 策略模式: 多选一。
- 责任链模式: 多步走。
实战
FishPi-Pyclient
在摸鱼派的 python 客户端里也使用了责任链模式来进行初始化,也是为了方便拓展和可读性。
摸鱼派 Python 客户端的初始化逻辑可以理解为这样
InitChain ↓ 调用 init() 初始化链 ↓ append() 添加每个 Initor(节点) Initor (抽象基类) ├── DefualtConfigInitor //生成默认配置 ├── EnvConfigInitor //从环境变量里读取配置并覆盖默认配置 ├── FileConfigInitor //从指定配置文件里读取配置并覆盖环境变量配置 ├── CilConfigInitor //从命令行启动参数里读取配置并覆盖配置文件里的配置 ├── LoginInitor //通过配置的参数登录摸鱼派 ├── BoloLoginInitor //如果填写了bolo账号密码,则进行bolo登录 ├── ChaRoomInitor //聊天室初始化 └── CliInitor //命令行指令接收器初始化
def init(self): self.append(DefualtConfigInitor(), EnvConfigInitor(), FileConfigInitor(), CilConfigInitor(), LoginInitor(), BoloLoginInitor(), ChaRoomInitor(), CliInitor()) self.head.init(self.api, self.options)
每个 Initor 通过 next
指向下一个处理节点,实现链式调用。新增或调整初始化步骤,仅需变动链的构造顺序,完全解耦逻辑与流程。
Netty
Netty 中的 ChannelPipeline
& ChannelHandler
Netty 作为高性能网络框架的标杆,其核心之一 ChannelPipeline
就是责任链模式的 教科书级应用 。
ChannelPipeline
(管道): 这就是那条 责任链 。它管理着所有处理网络事件的ChannelHandler
,并定义了事件在链上 传播的规则 (入站事件从头到尾,出站事件从尾到头)。ChannelHandler
(处理器): 这就是链上的一个个 处理器 。分为两大类:ChannelInboundHandler
:处理 入站事件 (如连接建立channelActive
、数据到达channelRead
、异常发生exceptionCaught
)。ChannelOutboundHandler
:处理 出站事件 (如连接请求connect
、数据写出write
、关闭连接close
)。
ChannelHandlerContext
(处理器上下文): 它封装了一个ChannelHandler
及其在Pipeline
中的位置信息。它是处理器 与链交互的桥梁 ,提供了:- 访问关联的
Channel
和Pipeline
。 - 最重要的
fire*
方法 (如fireChannelRead(Object msg)
),用于 将事件传递给链中的下一个处理器 。 - 读写操作等。
- 访问关联的
摸鱼派的 web 框架 latke 底层则是基于 Netty 实现的。
private void startServer(final SocketAddress socketAddress, final Class<? extends ServerChannel> channelClass) { try { InternalLoggerFactory.setDefaultFactory(Log4J2LoggerFactory.INSTANCE); new ServerBootstrap(). group(BOSS_GROUP, WORKER_GROUP). channel(channelClass). handler(new LoggingHandler(LogLevel.INFO)). childHandler(new HttpServerInitializer()). bind(socketAddress).sync().channel().closeFuture().sync(); } catch (final Exception e) { LOGGER.log(Level.ERROR, "Start server failed, exit process", e); System.exit(-1); } } private static final class HttpServerInitializer extends ChannelInitializer<Channel> { @Override public void initChannel(final Channel ch) { final ChannelPipeline pipeline = ch.pipeline(); // 1️⃣ 读超时处理器:如果12小时内没有读取到任何数据,关闭连接,防止资源被闲置连接占用。 pipeline.addLast(new ReadTimeoutHandler(12, TimeUnit.HOURS)); // 2️⃣ 写超时处理器:如果12小时内写操作阻塞/失败,关闭连接。 pipeline.addLast(new WriteTimeoutHandler(12, TimeUnit.HOURS)); // 3️⃣ HTTP 编解码器:将字节流 ↔️ HTTP 请求/响应对象,是 HTTP 支持的基础。 pipeline.addLast(new HttpServerCodec()); // 4️⃣ HTTP 消息聚合器:将多个 HTTP 分段(如多个 HttpContent)聚合成一个完整的 FullHttpRequest。 // 这是处理 POST 请求/大体积数据传输时的常见做法。 pipeline.addLast(new HttpObjectAggregator(Integer.MAX_VALUE)); // 5️⃣ WebSocket 压缩扩展支持:支持 WebSocket 帧的压缩和解压缩。 // 客户端启用压缩扩展时,可以减少网络流量。 pipeline.addLast(new WebSocketServerCompressionHandler()); // 6️⃣ 自定义 WebSocket 处理器:负责 WebSocket 握手、帧处理、心跳、广播等逻辑。 pipeline.addLast(new WebSocketHandler()); // 7️⃣ 最终的业务处理器:处理来自 HTTP/WebSocket 的请求消息 pipeline.addLast(new ServerHandler()); } }
欢迎来到这里!
我们正在构建一个小众社区,大家在这里相互信任,以平等 • 自由 • 奔放的价值观进行分享交流。最终,希望大家能够找到与自己志同道合的伙伴,共同成长。
注册 关于