四、函数写得长,加班加到爽

函数写得长,加班加到爽

第四章讲"函数",这章简直是为我这种"函数越写越长星人"量身定做的。看完才发现,自己以前写的不是函数,是"代码垃圾堆"。

函数的第一铁律:短小!再短小!

作者说"函数的第一规则是要短小,第二条规则是还要更短小"。看到这句话时,我默默打开自己上周写的一个800行长函数,羞愧地低下了头。

书中说函数应该短到"每个代码块都只有一行",最好是函数调用。想想也是,你看这段代码:

java 复制代码
// 反例
if (isTestPage) {
  // 10行设置代码
  // 20行处理逻辑
  // 5行清理工作
}

// 正例
if (isTestPage) {
  includeSetupAndTeardownPages();
}

后者一眼就能看出在干嘛,前者得逐行扒逻辑。函数长了,逻辑就藏起来了,debug时跟找针一样难。

函数只能做一件事,多一件都不行

作者说"函数应该做一件事,做好这件事,只做这件事"。但怎么判断是不是"一件事"呢?

一个简单的方法:看能不能再拆出一个函数,而且这个函数不只在重复解释原函数的实现。比如一个calculateOrder函数,如果里面既有计算价格,又有生成订单号,那肯定超标了。

想起之前写的submitForm函数,又验证表单、又调接口、又更新UI,改一个小逻辑就得通读全函数。现在才懂:函数做的事越多,被修改的理由就越多,出bug的概率就越大

函数的参数,越少越好

看到"最理想的参数数量是零"时,我惊了。但仔细想想,确实如此:

  • 无参数:getUserInfo() 一看就懂
  • 单参数:getUserById(id) 也还行
  • 双参数:calculateDistance(x1, y1, x2, y2) 开始混乱了
  • 多参数:createOrder(user, goods, address, coupon, payType) 堪称灾难

书中说"三元函数要特殊理由才能用",太对了。遇到多参数,不如封装成对象,比如createOrder(OrderParam param),既清晰又灵活。

最坑的是布尔参数,比如render(true),鬼知道这个true是"是否显示头部"还是"是否加载数据"?不如拆成renderWithHeader()renderWithoutHeader()

函数的命名,要像起外号一样精准

函数名必须准确描述它做的事。比如calculateTotalPrice()就比compute()好,validateUserSession()就比check()好。

更妙的是"动词+名词"的组合:saveUser()deleteOrder()generateToken(),读起来就像在说中文,根本不用猜。

想起自己以前给函数起名dealWithData(),现在看来就是摆烂------这函数到底是处理数据格式,还是过滤数据,还是计算数据?命名偷懒的代价,就是每次调用都要翻实现

错误处理别捣乱,单独放一边

作者说"try/catch块要单独抽成函数",深以为然。比如:

java 复制代码
// 反例
public void deletePage() {
  try {
    // 10行删除逻辑
  } catch (Exception e) {
    // 5行日志处理
  }
  // 还有20行其他逻辑
}

// 正例
public void deletePage() {
  try {
    doDeletePage();
  } catch (Exception e) {
    logDeleteError(e);
  }
}

private void doDeletePage() throws Exception {
  // 10行删除逻辑
}

private void logDeleteError(Exception e) {
  // 5行日志处理
}

后者把"删除"和"处理错误"彻底分开,逻辑一目了然。错误处理是必要的恶,但别让它弄脏主逻辑

最后动手改了个函数

把之前那个800行长函数拆成了12个小函数,每个函数都不超过20行。改完之后:

  • 同事说"终于能看懂了"
  • 改bug时不用翻来翻去了
  • 新增逻辑直接加新函数就行

突然明白,写短函数看似多花了时间,其实是在给未来的自己省钱。毕竟,调试3行函数的时间,比调试300行函数的时间,差了100倍

(下一章讲注释,想起自己写的"这里是循环"这种注释,感觉又要被骂了...)

相关推荐
cypking21 分钟前
electron中IPC 渲染进程与主进程通信方法解析
前端·javascript·electron
西陵27 分钟前
Nx带来极致的前端开发体验——借助playground开发提效
前端·javascript·架构
江城开朗的豌豆42 分钟前
Element UI动态组件样式修改小妙招,轻松拿捏!
前端·javascript·vue.js
float_六七1 小时前
JavaScript:现代Web开发的核心动力
开发语言·前端·javascript
zhaoyang03011 小时前
vue3笔记(2)自用
前端·javascript·笔记
德育处主任Pro2 小时前
# JsSIP 从入门到实战:构建你的第一个 Web 电话
前端
拾光拾趣录2 小时前
setTimeout(1) 和 setTimeout(2) 的区别
前端·v8
拾光拾趣录2 小时前
内存泄漏的“隐形杀手”
前端·性能优化
摸鱼仙人~2 小时前
HttpServletRequest深度解析:Java Web开发的核心组件
java·开发语言·前端
索西引擎2 小时前
【工程化】浅谈前端构建工具
前端·webpack·gulp·turbopack