| name | metaframe-null-object-pattern |
|---|---|
| category | engineering |
| description | 空对象模式 | Code & Engineering |
英文名: Null Object Pattern
分类: 编码实践
作者: Bobby Woolf, 1998; Martin Fowler, 2018
复杂度: beginner
成熟度: foundational
AI 相关: ❌ 否
通过提供实现预期接口的默认行为对象(无操作或安全默认值)来消除空值检查
- 空对象:接口的具体实现,提供中性的无操作行为作为 null 的替身
- 多态分派:使用类型系统将调用路由到空对象的方法,而非用条件语句防护
- 默认行为:空对象执行的安全、无副作用的操作,如返回空字符串、空列表或零
- 特殊情况模式:Martin Fowler 的泛化概念,任何特殊条件(不仅是 null)都由专用对象而非条件语句处理
- 哨兵值消除:用传达意图并防止错误的类型化对象替换魔术空值
- 识别普遍的空值检查:定位代码中为防范缺失的协作者或数据而散布的 null 或 nil 检查
- 定义接口或基类型:确保被检查空值的对象实现了定义预期行为的清晰接口或抽象类型
- 创建空对象类:用提供安全、中性默认行为的类实现接口 — 方法返回空集合、零值或简单地什么都不做
- 用空对象替换空值返回:修改工厂、仓库或查找方法,在找不到真实对象时返回空对象而非 null
- 移除空值检查:有了空对象之后,从调用代码中删除防御性空值检查,简化控制流并降低圈复杂度
['代码中充斥着对同一类型的重复空值检查,降低可读性并增加圈复杂度', '在具有可选协作者的系统中提供默认或访客行为,如 NullLogger 或 GuestUser', '方法返回 null 导致频繁 NullPointerException 或 TypeError 崩溃的遗留代码库', '通过使用空对象作为安全替身来简化测试代码,替代复杂的 mock 设置']
- 让空对象实现与真实对象相同的接口,因为多态性是该模式生效的关键
- 尽可能将空对象设为单例,因为没有理由创建多个相同默认行为的实例
- 清晰命名空对象(如 NullLogger、GuestUser、MissingCustomer),因为名称应传达其角色
- 考虑将语言级空安全特性(Optional、Option)与空对象结合使用,因为它们互为补充
- 不要将错误隐藏在空对象后面,因为有时 null 表示应该大声失败的真正 bug
- 当值的缺失具有重要的业务含义时不要使用空对象,因为静默吞咽会掩盖逻辑错误
- 不要为系统中每种类型都创建空对象类,因为这会产生不必要的样板代码
- 不要让空对象执行副作用,因为它的目的是惰性和安全的
Sources: SDFrame (Software Design) MetaFrame: 💻 Code & Engineering / 编码与工程