首页/开发/代码质量与评审速查/手法:Move Field(搬移字段)
重构手法62 条

手法:Move Field(搬移字段)

字段应和它主要服务的函数待在一起:把字段搬到使用更频繁的类,减少访问器转发;移动前用封装确认读写点,移动后运行测试验证。

Move Field 是什么

字段应当和主要使用它的函数待在一起:如果某个字段几乎只被另一个类访问,把它搬过去能让两个类的职责都更清楚,也减少一堆只为透传而存在的访问器。搬移字段比搬移函数影响面大——它牵扯数据、序列化格式与持久化结构,因此通常要分阶段推进而不是一次性改完。

基本信息

信号字段几乎只被另一个类访问
前置先 Encapsulate Variable 收敛读写点
步骤加新字段 → 双写 → 切换读 → 删旧字段
风险序列化与数据库列被外部引用,需要兼容期

推进要点

  • 先用访问器收口读写点,确认改动只在一处发生
  • 在新位置加字段,写入时两边同时写,读取仍走旧字段
  • 验证双写一致性:断言或对比任务确认两边一致
  • 切换读取到新字段,观察一个发布周期
  • 删除旧字段与双写逻辑,同步更新序列化与映射配置
  • 跨服务时按兼容策略推进:新增列先并行写,确认后再切读

迁移节奏

迁移节奏
阶段 1:新位置加字段,写入时双写
        write(value) { this.f = value; target.f = value; }
阶段 2:读取切换到新字段
        read() { return target.f; }
阶段 3:删除旧字段与双写逻辑

# 每阶段单独发布,观察一个周期再进入下一步
# 双写期必须有校验:定期对比两侧是否一致

各阶段与验证

阶段验证手段失败时
加字段结构变更脚本可重复执行回滚脚本
双写一致性对比任务报警修双写逻辑后再观察
切读关键路径回归测试把读切回旧字段
删旧检索确认无残留引用从版本历史恢复
搬移后要检查序列化与映射:字段名、JSON 键、数据库列若被外部引用,迁移期需保持双向兼容,否则下游会在你没察觉的时候读到空值。
双写但未校验一致性是最常见的半成品:底层存储两端悄悄分叉,等切换读取时才发现历史数据已经不一致。双写期一定要有一致性对比,哪怕是每天跑一次的离线任务。

易错点

  • 直接删旧字段无退路:发布失败时无法回滚,只能靠数据修复
  • 双写但未校验一致性:底层存储两端悄悄分叉,切读后问题集中爆发
  • 只搬字段不搬使用它的函数:依赖方向反而绕远,访问器增多
  • 忽略序列化兼容:外部按旧字段名读取,字段搬走后静默拿到空值

数据来源与参考

  • 《重构》第 2 版 · 第 8 章(Move Field)
​‌‌​​‌​​​‌‌​‌‌‌‌​‌‌​​​‌‌​‌‌‌​​‌‌​​‌​‌‌‌​​‌‌‌​​​‌​‌‌​‌​​‌​‌‌‌​​​‌​‌‌​‌​​‌​‌‌​​​‌‌​‌‌‌​‌​​​‌‌​‌‌‌‌​​‌​‌‌‌​​‌‌​​​‌‌​‌‌​‌‌‌‌​‌‌​‌‌​‌