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

函数写得长,加班加到爽

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

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

作者说"函数的第一规则是要短小,第二条规则是还要更短小"。看到这句话时,我默默打开自己上周写的一个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倍。

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

相关推荐
HSunR2 小时前
ruoyi 若依 自定义注解 参数校验
java·前端·数据库
拆房老料3 小时前
ONLYOFFICE也能像Microsoft Word和WPS一样分别设置中西文字体
前端·html·word·开源软件·wps
Solis程序员4 小时前
Stripe 幂等表:把「不确定的重试」变成「查表返回」
前端·安全·bootstrap·php·agent
李纲明4 小时前
WordPress 站点变慢:按 TTFB → 缓存 → 查询 → 前端 分层排查(含配置注意)
前端·缓存·性能优化·wordpress·后端开发
程序人生8884 小时前
PDF 转 Word 版式错乱、表格丢失?DocConverter Web 格式互转引擎的保真实践
前端·人工智能·opencv·机器学习·pdf·word
粥里有勺糖5 小时前
安利一下最近用的桌面“Agent” | T3 Code
前端·github·ai编程
xy34535 小时前
Axure 9.0 动态面板基本操作
前端·ui·html·axure·原型·产品设计
不停喝水5 小时前
【前端转全栈java速通课】 项目实战④7-11节 操作数据库-登录-注册-修改密码-注销-mubatis-plus简化crud-
java·前端·数据库
一水鉴天6 小时前
统一对象拓扑(UOT)设计全链定稿:从三件事分离到三继承 之1 20261010(豆包“查看聊天内容”继续)
前端·css
栖凤6 小时前
Java 的 try-catch 在 Agent 里失效了,我用了 5 个模式才兜住
java·前端·python