首页/开发/代码质量与评审速查/手法:Slide Statements(移动语句)
重构手法62 条

手法:Slide Statements(移动语句)

把相关语句聚到一起:变量声明贴近使用点、相关操作集中,为后续提炼创造条件;移动前确认语句之间没有隐藏依赖与副作用顺序。

是什么

移动语句(Slide Statements)把逻辑上相关的语句移到一起:变量声明贴近它的首次使用点,相关联的若干操作聚集为相邻段落。它本身不改变行为,却是很多后续重构的前提——相关代码聚在一起之后,才容易看出可以提炼成哪个函数。使用时通常与变量声明下移、循环外提等动作配合。

要点

目标相关代码相邻,降低阅读时的上下跳转
安全前提被移动的语句之间没有数据依赖与顺序敏感的副作用
常见后续常作为提炼函数的前置动作
反向操作拆分变量、内联变量等与声明位置相关的整理手法

典型使用场景

  • 函数开头集中声明大量变量:把声明下移到使用点,便于看出每段逻辑需要什么
  • 初始化与使用被无关语句隔开:聚拢后一眼看清数据从哪来、到哪去
  • 循环内外的计算位置不合理:把不随迭代变化的计算提到循环外
  • 提炼函数前的准备:把要提炼的语句先整理成连续块,再整体搬入新函数
  • 条件分支里逻辑分散:把同一分支相关的处理移到一处,减少来回对照

示例

示例
// 调整前:声明与使用之间隔着无关语句
int a = 1;
logStart();
int b = 2;
use(a);

// 调整后:声明贴近使用点
int a = 1;
use(a);
logStart();
int b = 2;

移动前检查

检查项关注点
数据依赖移动后是否有变量被提前引用或延后初始化
副作用顺序日志、写库、通知等顺序改变是否影响可观测结果
异常安全资源获取与释放是否被拆开,异常路径是否仍能释放
循环边界移动是否跨越循环边界,执行次数是否随之改变
并发可见性被移动的语句是否涉及共享状态,重排是否影响其他线程
移动语句属于低风险整理,但前提是读懂副作用。只要涉及写操作、外部调用或共享状态,就先确认顺序不敏感;拿不准时保留原顺序,先去处理更高的重构目标。
在带惰性求值或短路求值的语言里,重排可能改变表达式是否被求值:把有副作用的表达式移进或移出条件分支时,需要逐条核对。

落地检查清单

  • 移动的范围尽量小,一次只整理一段逻辑
  • 每次移动后跑一遍相关测试,而不是攒着一起验证
  • 整理完成后如果有可提炼的连续块,顺势提炼成函数
  • 保留原行为的注释,说明顺序为何不重要

易错点

  • 忽略异常安全顺序:把资源获取与释放拆开,异常路径下资源无法回收
  • 移动含副作用的语句:执行次数虽然相同,但时序变化导致日志或状态更新顺序错乱
  • 跨循环边界移动:把每次迭代都要执行的计算提到循环外,结果只算了一次
  • 只移动不看依赖:变量在使用点之后才赋值,出现空值或默认值参与计算

数据来源与参考

  • 《重构》第 2 版 · 第 8 章(Slide Statements)
​‌‌​​‌​​​‌‌​‌‌‌‌​‌‌​​​‌‌​‌‌‌​​‌‌​​‌​‌‌‌​​‌‌‌​​​‌​‌‌​‌​​‌​‌‌‌​​​‌​‌‌​‌​​‌​‌‌​​​‌‌​‌‌‌​‌​​​‌‌​‌‌‌‌​​‌​‌‌‌​​‌‌​​​‌‌​‌‌​‌‌‌‌​‌‌​‌‌​‌