重构与可读性:重构代码命名与结构,提升可读性

说实话,我见过太多代码了。有些代码像散文,读起来行云流水;有些代码像天书,看三行就想摔键盘。你猜哪种代码更容易出 Bug?

今天咱们聊聊可读性。这不是什么高大上的概念,说白了就是——别人(包括三个月后的你自己)能不能一眼看懂这段代码在干嘛

我个人习惯把可读性重构分成两个维度:命名结构。命名是微观层面的,结构是宏观层面的。两者缺一不可。

1. 命名:代码的「自我介绍」

先问个问题:你见过这样的变量名吗?

let a = 10;
let b = '张三';
let c = true;

嗯,我猜你见过。甚至可能写过。我在项目中遇到过最夸张的一次,有个同事用 a1a2a3 命名了十几个变量,最后他自己都分不清哪个是哪个了。

好的命名应该做到:看到名字就知道用途

核心原则:

  • 变量名用名词,函数名用动词
  • 避免缩写,除非是行业通用缩写(如 HTML、API)
  • 长度适中:太短含义不清,太长影响阅读

举个例子,这是重构前的代码:

function calc(a, b) {
  return a * b + a * 0.1;
}

你能看出这个函数在算什么吗?反正我看不出来。重构一下:

function calculateTotalPrice(basePrice, quantity) {
  const taxRate = 0.1;
  return basePrice * quantity + basePrice * taxRate;
}

现在是不是清晰多了?calculateTotalPrice 告诉你这是算总价的,basePrice 是单价,quantity 是数量,taxRate 是税率。一目了然。

小技巧:命名时试着用英文完整描述变量的含义。比如 userListlist 好,activeUserListuserList 更好。但别走极端,listOfAllActiveUsersInTheCurrentSession 就太长了。

2. 结构:代码的「骨架」

命名搞定了,接下来看结构。结构问题往往比命名问题更隐蔽,也更致命。

我曾经接手过一个项目,一个函数写了 800 行。对,你没看错,800 行。里面混杂着数据库查询、业务逻辑、前端渲染、日志打印……我当时的心情,怎么说呢,就像打开了一个潘多拉魔盒。

好的结构应该遵循单一职责原则:一个函数只做一件事。

来看个例子:

function processOrder(order) {
  // 验证订单
  if (!order.items || order.items.length === 0) {
    throw new Error('订单为空');
  }
  if (!order.userId) {
    throw new Error('用户未登录');
  }

  // 计算价格
  let total = 0;
  for (let item of order.items) {
    total += item.price * item.quantity;
  }
  if (order.coupon) {
    total = total * 0.9;
  }

  // 保存订单
  const savedOrder = database.save(order);
  
  // 发送通知
  email.send(order.userId, '订单已确认');
  
  return savedOrder;
}

这个函数干了四件事:验证、计算、保存、通知。拆开它:

function validateOrder(order) {
  if (!order.items || order.items.length === 0) {
    throw new Error('订单为空');
  }
  if (!order.userId) {
    throw new Error('用户未登录');
  }
}

function calculateTotal(order) {
  let total = 0;
  for (let item of order.items) {
    total += item.price * item.quantity;
  }
  if (order.coupon) {
    total = total * 0.9;
  }
  return total;
}

function processOrder(order) {
  validateOrder(order);
  const total = calculateTotal(order);
  const savedOrder = database.save({ ...order, total });
  email.send(order.userId, '订单已确认');
  return savedOrder;
}

现在 processOrder 变成了一个「指挥者」,它调用各个子函数。每个子函数只做一件事,测试起来也方便。你想测试价格计算逻辑?直接测 calculateTotal 就行,不用管验证和保存。

注意:拆分的粒度要适中。别把一个函数拆成十几个只有两三行的小函数,那样反而会增加阅读负担。我一般遵循「一个函数不超过 20 行」的原则,但这不是硬性规定,看具体情况。

3. 知识体系:一张图看懂

说了这么多,咱们用一张图来总结一下可读性重构的核心逻辑:

可读性重构 命名重构 变量名用名词,函数名用动词 避免无意义缩写 长度适中,含义清晰 结构重构 单一职责原则 函数不超过20行 拆分长函数为小函数 提升可读性

这张图展示了可读性重构的两个核心维度:命名和结构。两者相辅相成,缺一不可。命名好了,结构乱了,代码依然难读;结构好了,命名烂了,同样让人头疼。

4. 避坑指南

最后分享几个我踩过的坑:

  • 过度抽象:我曾经为了「优雅」,把一个简单的 if-else 拆成了五个类加三个接口。结果呢?后来改需求的时候,我自己都找不到逻辑在哪。记住:可读性优先于「设计模式」
  • 注释当拐杖:如果代码需要大量注释才能看懂,说明代码本身有问题。好的代码应该是自解释的。注释应该解释「为什么」,而不是「是什么」。
  • 忽略上下文:在某个模块里,getData 可能很清楚是获取用户数据。但在全局范围内,这个命名就太模糊了。命名时要考虑调用者的视角。

我的习惯:写完代码后,我会假装自己是第一次看到这段代码。如果三秒钟内看不懂某个变量或函数的作用,就说明命名或结构需要改进。这个方法虽然简单,但非常有效。

可读性重构不是锦上添花,而是雪中送炭。它直接关系到代码的维护成本、Bug 率,甚至团队的工作效率。下次写代码时,多花 30 秒想想命名和结构,你会感谢自己的。

公众号:蓝海资料掘金营,微信deep3321