是什么
移动语句(Slide Statements)把逻辑上相关的语句移到一起:变量声明贴近它的首次使用点,相关联的若干操作聚集为相邻段落。它本身不改变行为,却是很多后续重构的前提——相关代码聚在一起之后,才容易看出可以提炼成哪个函数。使用时通常与变量声明下移、循环外提等动作配合。
要点
| 目标 | 相关代码相邻,降低阅读时的上下跳转 |
|---|---|
| 安全前提 | 被移动的语句之间没有数据依赖与顺序敏感的副作用 |
| 常见后续 | 常作为提炼函数的前置动作 |
| 反向操作 | 拆分变量、内联变量等与声明位置相关的整理手法 |
典型使用场景
- 函数开头集中声明大量变量:把声明下移到使用点,便于看出每段逻辑需要什么
- 初始化与使用被无关语句隔开:聚拢后一眼看清数据从哪来、到哪去
- 循环内外的计算位置不合理:把不随迭代变化的计算提到循环外
- 提炼函数前的准备:把要提炼的语句先整理成连续块,再整体搬入新函数
- 条件分支里逻辑分散:把同一分支相关的处理移到一处,减少来回对照
示例
示例
// 调整前:声明与使用之间隔着无关语句
int a = 1;
logStart();
int b = 2;
use(a);
// 调整后:声明贴近使用点
int a = 1;
use(a);
logStart();
int b = 2;移动前检查
| 检查项 | 关注点 |
|---|---|
| 数据依赖 | 移动后是否有变量被提前引用或延后初始化 |
| 副作用顺序 | 日志、写库、通知等顺序改变是否影响可观测结果 |
| 异常安全 | 资源获取与释放是否被拆开,异常路径是否仍能释放 |
| 循环边界 | 移动是否跨越循环边界,执行次数是否随之改变 |
| 并发可见性 | 被移动的语句是否涉及共享状态,重排是否影响其他线程 |
移动语句属于低风险整理,但前提是读懂副作用。只要涉及写操作、外部调用或共享状态,就先确认顺序不敏感;拿不准时保留原顺序,先去处理更高的重构目标。
在带惰性求值或短路求值的语言里,重排可能改变表达式是否被求值:把有副作用的表达式移进或移出条件分支时,需要逐条核对。
落地检查清单
- 移动的范围尽量小,一次只整理一段逻辑
- 每次移动后跑一遍相关测试,而不是攒着一起验证
- 整理完成后如果有可提炼的连续块,顺势提炼成函数
- 保留原行为的注释,说明顺序为何不重要