讲师中心 微信公众号
AI工具推荐 视频效率加速

设计模式之策略模式_利用多态消除繁琐的if-else

阿静酱_2382

阿静酱_2382

发布时间:2026-02-24 15:07:03

|

556人浏览过

|

来源于php中文网

原创

策略模式仅适用于同一行为的多实现、分支≥3、易扩展且逻辑复杂度相近的场景;滥用会导致代码臃肿,应避免为简单分支创建过多策略类。

设计模式之策略模式_利用多态消除繁琐的if-else

策略模式该不该用来替换所有 if-else

不是所有 if-else 都值得动用策略模式。只有当条件分支基于**同一行为的不同实现**,且分支数量 ≥ 3、未来可能新增、各分支逻辑复杂度接近时,才真正需要它。否则硬套只会让代码更难读。

常见错误现象:if (type === 'A') { ... } else if (type === 'B') { ... } 里每个分支只有一两行简单赋值或日志,却为此建了 5 个策略类——这是在给维护者添堵。

  • 使用场景:支付方式(AlipayStrategy / WechatPayStrategy / CardPayStrategy)、折扣计算(FullReductionRule / PercentOffRule / BuyOneGetOneRule)
  • 参数差异:所有策略类必须实现统一接口,比如 execute(input: any): Result,不能一个要 context,另一个要 config
  • 性能影响:策略对象通常需提前实例化或懒加载,频繁创建会增加 GC 压力;若分支极少且执行极快,直接 if-else 反而更轻量

如何避免策略注册表变成新 if-else

很多人把策略存进 Map 或对象,再用 strategyMap.get(type) 获取,但初始化这个 map 时又写了一堆 if (type === 'X') map.set('X', new XStrategy()) ——等于把 if-else 搬了个家。

正确做法是让策略“自注册”或靠配置驱动:

  • 使用装饰器(TypeScript)或注解(Java),让每个策略类声明自己支持的 type,启动时自动扫描注册
  • 用 JSON 配置文件定义 type → class 名映射,运行时动态 require() 或反射加载(注意 Node.js 的 require.cache 和 Webpack 的 tree-shaking 影响)
  • 最简方案:用 Object literal 直接写死映射,但确保 key 和 value 类型一致,例如 { 'vip': VipDiscount, 'student': StudentDiscount },别混入字符串或函数

策略类里还能不能再有 if-else

能,但仅限于**当前策略内部的细粒度判断**,比如 StudentDiscount.execute() 里按年级分折扣率:if (grade === 'freshman') { ... }。这不破坏策略模式契约,因为对外仍是单一行为入口。

容易踩的坑:

  • 在策略基类或上下文类(Context)里写跨策略的 if-else,比如根据用户地区决定用哪个策略——这说明策略划分维度错了,应该把地区纳入策略选择逻辑,而不是藏在某个策略内部
  • 策略类之间互相调用或继承,导致依赖混乱;策略应彼此隔离,只共享输入输出结构
  • 把状态(如用户登录态、库存余量)塞进策略构造函数,却不校验是否为空或过期,运行时报 Cannot read property 'xxx' of undefined

TypeScript 下类型安全怎么兜住

光靠 interface 约束 execute() 方法签名不够。如果策略返回类型不同(比如有的返回 Promise<void></void>,有的返回 string),调用方就无法安全处理。

实操建议:

  • 定义泛型策略接口:interface Strategy<tinput toutput> { execute(input: TInput): TOutput }</tinput>,强制每个策略明确自己的输入输出
  • 注册表类型写成 Record<string strategy commonoutput>></string>,逼迫所有策略收敛到公共类型,必要时用联合类型或 discriminated union 包装差异字段
  • 别忽略 unknown 到 any 的转换风险:从配置读取的 type 字符串必须经过 Object.keys(strategyMap).includes(rawType) 校验,否则 strategyMap[rawType as keyof typeof strategyMap] 会绕过类型检查

最常被忽略的一点:策略的生命周期和上下文耦合。比如一个策略依赖 HttpClient 实例,但没做依赖注入或传参隔离,多个请求并发时共享连接池或 token,结果 A 用户看到 B 用户的数据——这不是模式问题,是设计落地时忘了“策略是无状态的”这个前提。

本站声明:本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系admin@php.cn

热门AI工具

更多
PixPix
PixPix Hot

PixPix是一款面向电商视觉生产的AI商品图生成工具。

小橡皮AI

一款AI工具,主要用于小橡皮一键去AI味,将机器味重的内容改得更有活人感,防止因为 AI 内容被平台打上 AI 标签,以及限流,适合需要提升相关任务效率的用户。

豆包大模型

豆包大模型是一款由字节跳动推出的企业级大语言模型服务平台。

DeepSeek

DeepSeek是一款面向对话、写作、编程和推理场景的AI大模型工具。

切问学术

切问学术是一款AI论文写作工具,复旦大学NLP团队推出的AI学术智能体。

SkildArt
SkildArt Hot

SkildArt是一款AI文本写作工具,一站式 AI 视觉创作平台。

UpDream
UpDream Hot

一款AI视频创作工具,主要用于哔哩哔哩推出的自研AI视频创作工具,适合需要提升相关任务效率的用户。

创客贴AI

创客贴AI是一款AI图像与设计工具,AI辅助的智能在线设计工具。

WorkBuddy

一款AI办公效率工具,主要用于腾讯云推出的AI原生桌面智能体工作台,适合需要提升相关任务效率的用户。

相关专题

更多
TypeScript工程化开发与Vite构建优化实践
TypeScript工程化开发与Vite构建优化实践

本专题面向前端开发者,深入讲解 TypeScript 类型系统与大型项目结构设计方法,并结合 Vite 构建工具优化前端工程化流程。内容包括模块化设计、类型声明管理、代码分割、热更新原理以及构建性能调优。通过完整项目示例,帮助开发者提升代码可维护性与开发效率。

312

2026.02.13

TypeScript全栈项目架构与接口规范设计
TypeScript全栈项目架构与接口规范设计

本专题面向全栈开发者,系统讲解基于 TypeScript 构建前后端统一技术栈的工程化实践。内容涵盖项目分层设计、接口协议规范、类型共享机制、错误码体系设计、接口自动化生成与文档维护方案。通过完整项目示例,帮助开发者构建结构清晰、类型安全、易维护的现代全栈应用架构。

520

2026.02.25

TypeScript类型系统进阶与大型前端项目实践
TypeScript类型系统进阶与大型前端项目实践

本专题围绕 TypeScript 在大型前端项目中的应用展开,深入讲解类型系统设计与工程化开发方法。内容包括泛型与高级类型、类型推断机制、声明文件编写、模块化结构设计以及代码规范管理。通过真实项目案例分析,帮助开发者构建类型安全、结构清晰、易维护的前端工程体系,提高团队协作效率与代码质量。

371

2026.03.13

TypeScript 全栈开发进阶指南
TypeScript 全栈开发进阶指南

面向有 JavaScript 基础的开发者,深入讲解 TypeScript 的类型系统与全栈开发实践。

286

2026.06.03

TypeScript Node.js 全栈工程化与Monorepo架构实践
TypeScript Node.js 全栈工程化与Monorepo架构实践

本专题围绕 TypeScript 在 Node.js 全栈开发中的工程化实践展开,系统讲解 Monorepo 架构设计、包管理策略、模块复用机制以及服务端与前端统一类型系统的构建方法。通过真实项目案例,帮助开发者提升大型全栈项目的可维护性与协作效率。

658

2026.06.16

json数据格式
json数据格式

JSON是一种轻量级的数据交换格式。本专题为大家带来json数据格式相关文章,帮助大家解决问题。

2175

2023.08.07

json是什么
json是什么

JSON是一种轻量级的数据交换格式,具有简洁、易读、跨平台和语言的特点,JSON数据是通过键值对的方式进行组织,其中键是字符串,值可以是字符串、数值、布尔值、数组、对象或者null,在Web开发、数据交换和配置文件等方面得到广泛应用。本专题为大家提供json相关的文章、下载、课程内容,供大家免费下载体验。

3422

2023.08.23

jquery怎么操作json
jquery怎么操作json

操作的方法有:1、“$.parseJSON(jsonString)”2、“$.getJSON(url, data, success)”;3、“$.each(obj, callback)”;4、“$.ajax()”。更多jquery怎么操作json的详细内容,可以访问本专题下面的文章。

1136

2023.10.13

Gradle插件开发入门教程
Gradle插件开发入门教程

本专题介绍Gradle插件开发的基本流程,涵盖插件类编写、自定义任务注册、扩展参数设计和插件应用方法,帮助你理解插件如何组织构建逻辑,减少多个项目之间的重复配置。

60

2026.10.22

热门下载

更多
网站特效
/
网站源码
/
网站素材
/
前端模板

精品课程

更多
热门推荐
/
最新课程
关于我们 免责申明 举报中心 意见反馈 讲师合作 广告合作 最新更新
php中文网:公益在线php培训,帮助PHP学习者快速成长!
关注服务号
PHP中文网订阅号
每天精选资源文章推送

Copyright 2014-2026 https://www.php.cn/ All Rights Reserved | php.cn