你大概已经听过无数次:“让代码保持简单”。
几乎每个资深开发者、每本讲求整洁代码的书、每家工程博客都在强调同一个目标:
写出简单的代码。
因为简单的代码更易维护、更易阅读,也通常更高效。
可为什么现实里,还是到处能见到复杂混乱的代码呢?
原因就在于,“写简单的代码”本身并不简单。
表面看起来简单,做起来却困难
当你看到一段写得恰到好处的代码,你会觉得“这不就应该这样写吗?”
仿佛所有逻辑都显而易见、所有架构都自然而然。
但要达到这种清晰度,往往需要相当多的迭代、经验和思考。
不少开发者,尤其是初入行时,很容易把“复杂”与“聪明”划等号。他们会刻意往系统里加各种抽象、扩展性、配置项,觉得这样很“高级”。他们提前为未来做一堆假设,结果反而把自己陷入凌乱的抽象网络里。
简单的代码则截然不同,它绝不是随随便便写出来的。需要你有:
- 经验:写过并调试过一大堆过度复杂、难维护的代码后,才会知道要避免什么。
- 克制:不乱加抽象和配置,其实比往里加功能更难。
- 明晰的取舍:你无法一次性满足所有需求。有时候不得不在灵活性、性能或简洁度之间做牺牲。
复杂的幻象
这其中还存在一种心理错觉:看到一段复杂的代码,往往会以为它是在解决一个很复杂的问题。“既然写得这么复杂,那肯定很高深吧?”其实未必。
有时复杂只是因为作者拿不定主意:
- 不知道哪种方式更好,就都加进去
- “万一以后要用呢?”就为此多写一层封装
结果系统到处是多余的函数、配置和选项,既难理解又难调试。
常见导致复杂的“坑”
如果想写简单的代码,先要弄清楚代码为什么会变得复杂。以下几个是最典型的陷阱:
- 过度抽象:并不是每个函数都要适配所有可能场景。有时明文写出具体逻辑,比写一堆“泛用”但是迷糊的抽象要好。
- 过早优化:很多人一上来就想把所有功能都做成“可伸缩”的,但实际上可能永远用不到那些扩展。先解决当前问题比较要紧。
- 过多层级:在封装之外又封装,再包一层外壳——每加一层,对理解和维护都是额外负担。
- “功能繁多”却没场景:为将来的需求而做的臆想功能,往往会成为累赘。“YAGNI”(You Ain't Gonna Need It)就是劝你别为不确定的需求去写多余的代码。
- 不必要的配置:有些人喜欢把一切都做成可配的,但往往默认值就足够应付大部分场景。
实用建议:怎样让代码更简单?
让代码保持简单不代表只写短代码,而是要写更易懂、更直观的代码。可以试试:
- 自解释式的命名:变量和函数名要能说明做了什么。如果必须要写大量注释解释函数的用途,说明逻辑可能需要拆分或命名需要改进。
- 限制抽象层级:没发现真正的复用需求前,先别急着搞抽象工厂、复杂继承或深层嵌套。
- 遵循“约定优于配置”:与其自己再写一堆配置,不如先用主流或社区的最佳实践,一致性带来的可维护性往往更高。
- 持续重构:只要觉得哪块代码读起来“别扭”,就重写或简化。让它保持干净是一个长期过程。
- 关注可读性:想象一下,半年前写的代码,今天再看是否能立刻明白?如果答案是否定的,就该考虑如何让它更清晰。
简单的代码,需要“狠心”
写简单代码最难的部分,往往是做取舍。
哪些功能是真的需要可扩展?哪些部分完全可以写死?这层抽象究竟是在解决实际问题,还是只是在满足你的“炫技”欲望?
好的开发者有能力排除噪音,剔除不必要的东西,为可维护性和可理解度优先买单。这需要果断和经验。
最后的想法
其实人人都能写出复杂的代码,因为把想法不停地塞进去最轻松了。
但要把代码“减负”,只留下必要的核心,这才是真正的挑战。
简洁不是起点,而是不断打磨和舍弃后的成果。
下次你觉得自己开始“过度设计”时,不妨问问自己:“我是因为真的需要,还是仅仅因为我能这么做而已?”