首页/开发/代码质量与评审速查/坏味道:过长函数(Long Function)
重构手法62 条

坏味道:过长函数(Long Function)

函数越长越难理解与测试;处理路径是提取与分解:注释分段、条件分支、循环体都可以提炼为命名函数,长度只是信号,可理解性才是目标。

过长函数为什么是问题

函数越长,越难理解、越难测试、越难复用:读的人需要在脑子里一次装下太多状态,改动时也很难判断影响范围。处理路径是提取与分解——把注释当作段落标题的代码块、条件分支、循环体都可以提炼成有名字的函数。长度只是信号,可理解性才是目标。

基本信息

信号需要滚动多屏才能读完;注释充当段落标题
常用手法提炼函数、分解条件表达式、用查询替代临时变量
判断标准函数是否在做多件事,每件事能否被命名
收益每段逻辑可单独命名、单独测试、单独复用

分解的思路

  • 把注释当作待提炼的清单:每条解释意图的注释都是一个候选函数名。
  • 先处理条件分支:把复杂的条件表达式提炼成命名清晰的判断函数。
  • 循环体独立出来:循环内做多件事时,先提炼循环体再简化循环本身。
  • 减少临时变量:用查询替代临时变量,能明显降低提炼难度。
  • 按层次组织:外层函数描述步骤,细节下沉到被调用的小函数里。
  • 注释充当分隔线时就是拆分信号:能被一条注释概括的一段,通常也可以成为一个命名函数。

分解思路示例

分解思路示例
parseOrder() {
    validate(order);
    price = priceOf(order);
    discounts = discountFor(order);
    receipt = receiptOf(order, price, discounts);
}

长函数的典型成因

成因处理方向
注释充当段落标题把每段提炼成命名函数
条件分支嵌套过深分解条件表达式,提前返回
循环内混合多种职责提炼循环体,分离数据处理与输出
临时变量过多用查询替代临时变量
顺序依赖的多个步骤按步骤提炼成独立方法
判断标准不是行数阈值,而是:函数是否在做多件事、每件事是否可以被命名。
提炼后函数数量会变多:命名清晰、层次分明时,阅读成本反而下降,因为读者可以按层次选择阅读深度。
拆分前后都要跑一遍测试:长函数牵涉的状态较多,机械修改也容易顺手改错。

易错点

  • 按行数一刀切(超过某个行数必拆):机械拆分产生碎片、语义断裂。
  • 提取时把大量临时变量变成参数:参数列表膨胀,引入新的坏味道。
  • 拆出的函数命名含糊(如 handle、process):等于把长函数切成了更难看懂的小块。
  • 只拆不整理:碎片化后缺少层次组织,读代码要在多个函数间反复跳。

数据来源与参考

  • 《重构》第 2 版 · 第 3 章(Long Function)
​‌‌​​‌​​​‌‌​‌‌‌‌​‌‌​​​‌‌​‌‌‌​​‌‌​​‌​‌‌‌​​‌‌‌​​​‌​‌‌​‌​​‌​‌‌‌​​​‌​‌‌​‌​​‌​‌‌​​​‌‌​‌‌‌​‌​​​‌‌​‌‌‌‌​​‌​‌‌‌​​‌‌​​​‌‌​‌‌​‌‌‌‌​‌‌​‌‌​‌