Move Field 是什么
字段应当和主要使用它的函数待在一起:如果某个字段几乎只被另一个类访问,把它搬过去能让两个类的职责都更清楚,也减少一堆只为透传而存在的访问器。搬移字段比搬移函数影响面大——它牵扯数据、序列化格式与持久化结构,因此通常要分阶段推进而不是一次性改完。
基本信息
| 信号 | 字段几乎只被另一个类访问 |
|---|---|
| 前置 | 先 Encapsulate Variable 收敛读写点 |
| 步骤 | 加新字段 → 双写 → 切换读 → 删旧字段 |
| 风险 | 序列化与数据库列被外部引用,需要兼容期 |
推进要点
- 先用访问器收口读写点,确认改动只在一处发生
- 在新位置加字段,写入时两边同时写,读取仍走旧字段
- 验证双写一致性:断言或对比任务确认两边一致
- 切换读取到新字段,观察一个发布周期
- 删除旧字段与双写逻辑,同步更新序列化与映射配置
- 跨服务时按兼容策略推进:新增列先并行写,确认后再切读
迁移节奏
迁移节奏
阶段 1:新位置加字段,写入时双写
write(value) { this.f = value; target.f = value; }
阶段 2:读取切换到新字段
read() { return target.f; }
阶段 3:删除旧字段与双写逻辑
# 每阶段单独发布,观察一个周期再进入下一步
# 双写期必须有校验:定期对比两侧是否一致各阶段与验证
| 阶段 | 验证手段 | 失败时 |
|---|---|---|
| 加字段 | 结构变更脚本可重复执行 | 回滚脚本 |
| 双写 | 一致性对比任务报警 | 修双写逻辑后再观察 |
| 切读 | 关键路径回归测试 | 把读切回旧字段 |
| 删旧 | 检索确认无残留引用 | 从版本历史恢复 |
搬移后要检查序列化与映射:字段名、JSON 键、数据库列若被外部引用,迁移期需保持双向兼容,否则下游会在你没察觉的时候读到空值。
双写但未校验一致性是最常见的半成品:底层存储两端悄悄分叉,等切换读取时才发现历史数据已经不一致。双写期一定要有一致性对比,哪怕是每天跑一次的离线任务。