事件委托结合策略模式可将臃肿的if-else分支解耦为可复用、可测试、可插拔的策略对象,父级仅负责识别目标并调度,策略内部专注逻辑执行且支持动态注册、上下文隔离与状态驱动。

事件委托本身是利用冒泡机制把子元素事件统一交给父级处理,而策略模式则是把不同行为封装成独立的“策略类”,运行时按条件选择执行哪个。两者结合,能把原本臃肿的 if-else 或 switch 分支点击逻辑,拆解为可复用、可测试、可插拔的行为单元。
用策略对象替代硬编码分支
传统写法常在事件回调里写一堆判断:
-
e.target.matches('.btn-edit')→ 执行编辑逻辑 -
e.target.matches('.btn-delete')→ 弹确认框并删数据 -
e.target.matches('.btn-export')→ 触发下载 - ……可能还有十多个类似分支,且每块逻辑混着DOM操作、API调用、状态更新
重构后,每个按钮类型对应一个策略对象,比如:
Java项目代码review工具。分析Git变更+完整调用链路上下文,推断业务需求,进行多维度评分和分类汇总,生成完整PRD文档。包含细粒度Java代码审查清单(Null安全、异常处理、Streams、并发、equals/hashCode、资源管理、API设计、性能、MyBatis/ORM、事务边界、SQL/DD...
const strategies = {
'btn-edit': {
exec: (target, context) => {
const row = target.closest('.row');
openEditModal(row.dataset.id);
}
},
'btn-delete': {
exec: (target, context) => {
const id = target.closest('.row')?.dataset.id;
if (confirm('确定删除?')) api.delete(id).then(() => refreshList());
}
},
'btn-export': {
exec: (target, context) => downloadAsCSV(context.data || [])
}
};
委托入口统一调度,不耦合具体行为
父级只负责识别目标、查策略、执行,不关心“怎么删”或“怎么导出”:
- 监听 document 或容器根节点的 click
- 用
e.target.closest('[data-action]')或e.target.matches('.btn-*')提取动作标识 - 从
strategies中取出对应策略,传入 target 和上下文(如当前列表数据、用户权限等) - 调用
strategy.exec(target, context),策略内部自行处理副作用
支持动态注册与上下文隔离
策略不是静态配置,可以按需加载或切换:
- 权限变化时,动态增删策略:
strategies['btn-admin'] = adminOnlyStrategy - 不同模块使用不同策略集,避免全局污染:
TableStrategyRegistry.get('user-table').handle(e) - 策略内部可依赖注入(如 service、store),不直接操作全局变量或 DOM
- 便于单元测试:每个策略可单独 mock 依赖,验证输入输出
配合状态驱动,避免手动管理 UI 副作用
策略只负责“做什么”,UI 反馈由统一状态层控制:
- 策略执行前触发 loading 状态(如
setPending(true)) - 成功后 dispatch action,让 reducer 更新 UI(而非策略里直接
el.remove()) - 错误时统一 toast 提示,不散落在各策略中重复写
alert() - 这样策略保持纯逻辑,UI 交由响应式框架或 CSS class 控制
Java免费学习笔记:立即使用
解锁 Java 大师之旅:从入门到精通的终极指南










