原文链接: https://interview.poetries.top/docs/base/design-pattern.html
设计模式 2
简版速记
面试速记:设计模式的本质是「针对接口编程、把变化隔离起来」。下面按类别给出最常被追问的要点,先记口诀再看正文细节。
基础三问(必背)
- this 指向:调用时确定,不看声明位置。优先级
new>bind/call/apply显式绑定 > 对象方法(隐式绑定)> 默认绑定(严格模式下为undefined,非严格为全局对象)。箭头函数没有自己的 this,捕获定义时所在词法作用域的 this,且不能被bind/call/apply改变。 - 原型链与继承:实例
__proto__→ 构造函数prototype→ 逐级向上至Object.prototype→null。ES6class extends是组合继承的语法糖,子类必须先super()才能用this;super解决了 ES5 寄生组合继承中手动修正constructor、避免父构造函数被调用两次的痛点。 - 设计原则(SOLID 速记):单一职责、开闭(对扩展开放对修改关闭)、里氏替换、接口隔离、依赖倒置。设计模式都是这些原则的落地手段。
23 种模式按类别
| 类别 | 模式 | 一句话用途 |
|---|---|---|
| 创建型 | 单例 | 全局唯一实例 + 全局访问点(登录弹窗、Store、连接池) |
| 创建型 | 工厂 / 抽象工厂 | 把对象创建逻辑收口,调用方不关心 new 哪个类 |
| 创建型 | 建造者 | 分步装配复杂对象,分离「构建过程」与「最终表示」 |
| 结构型 | 代理 | 在不改原对象的前提下加控制层(缓存、节流、懒加载、保护) |
| 结构型 | 适配器 | 接口转换,让不兼容的接口协同工作(jQuery.ajax → Axios) |
| 结构型 | 装饰者 | 运行时动态叠加功能,不改原类(AOP、@decorator) |
| 结构型 | 外观 | 给一组子系统提供统一简化入口($.ajax、SDK 封装) |
| 结构型 | 享元 / 组合 / 桥接 | 共享细粒度对象省内存 / 树形结构统一处理 / 抽象与实现解耦 |
| 行为型 | 发布-订阅 / 观察者 | 解耦事件的发送方与接收方(EventBus、Vue 响应式、Promise) |
| 行为型 | 策略 | 用映射表替代大段 if-else,算法可插拔(表单校验、折扣计算) |
| 行为型 | 状态 | 把状态机的每个状态封装成对象,消除散落的状态判断 |
| 行为型 | 模板方法 / 迭代器 / 命令 / 职责链 / 中介者 | 固定骨架延迟实现 / 统一遍历 / 请求封装成对象 / 请求沿链传递 / 多对多解耦为星形 |
前端高频对应(面试官最爱问「举个真实例子」)
- 代理模式:图片懒加载、虚拟代理预加载、ES6
Proxy(Vue3 响应式底层)。 - 发布-订阅 vs 观察者:观察者是目标直接通知观察者(强耦合),发布-订阅多了一个事件中心(调度中心)做中转,发布方与订阅方互不感知。
- 策略 vs 状态:都用对象映射消灭 if-else;策略的算法之间平行无关、由客户端选择,状态的各状态之间会相互流转、由内部驱动切换。
- 装饰者 vs 代理:装饰者强调「增强功能」,可层层叠加;代理强调「控制访问」,通常一层。
补充(现代做法):实际工程里很多经典模式已被语言特性或框架内建。单例直接用 ES Module(模块天然单例);观察者/发布-订阅在 Vue3 用
Proxy+ 依赖收集、React 用useSyncExternalStore或 Context;策略/状态机推荐用 XState 这类状态机库;命令模式对应 Redux 的 action + reducer。面试时能点出「这个模式在 XXX 框架里是如何被吸收的」往往比手写实现更加分。
