Skip to content

Latest commit

 

History

History
58 lines (42 loc) · 2.95 KB

File metadata and controls

58 lines (42 loc) · 2.95 KB
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)都由专用对象而非条件语句处理
  • 哨兵值消除:用传达意图并防止错误的类型化对象替换魔术空值

使用步骤

  1. 识别普遍的空值检查:定位代码中为防范缺失的协作者或数据而散布的 null 或 nil 检查
  2. 定义接口或基类型:确保被检查空值的对象实现了定义预期行为的清晰接口或抽象类型
  3. 创建空对象类:用提供安全、中性默认行为的类实现接口 — 方法返回空集合、零值或简单地什么都不做
  4. 用空对象替换空值返回:修改工厂、仓库或查找方法,在找不到真实对象时返回空对象而非 null
  5. 移除空值检查:有了空对象之后,从调用代码中删除防御性空值检查,简化控制流并降低圈复杂度

适用场景

['代码中充斥着对同一类型的重复空值检查,降低可读性并增加圈复杂度', '在具有可选协作者的系统中提供默认或访客行为,如 NullLogger 或 GuestUser', '方法返回 null 导致频繁 NullPointerException 或 TypeError 崩溃的遗留代码库', '通过使用空对象作为安全替身来简化测试代码,替代复杂的 mock 设置']

最佳实践

✅ 推荐做法

  • 让空对象实现与真实对象相同的接口,因为多态性是该模式生效的关键
  • 尽可能将空对象设为单例,因为没有理由创建多个相同默认行为的实例
  • 清晰命名空对象(如 NullLogger、GuestUser、MissingCustomer),因为名称应传达其角色
  • 考虑将语言级空安全特性(Optional、Option)与空对象结合使用,因为它们互为补充

❌ 避免做法

  • 不要将错误隐藏在空对象后面,因为有时 null 表示应该大声失败的真正 bug
  • 当值的缺失具有重要的业务含义时不要使用空对象,因为静默吞咽会掩盖逻辑错误
  • 不要为系统中每种类型都创建空对象类,因为这会产生不必要的样板代码
  • 不要让空对象执行副作用,因为它的目的是惰性和安全的

Sources: SDFrame (Software Design) MetaFrame: 💻 Code & Engineering / 编码与工程