编程两三事:辞达而已矣
2026年,新年新气象。最近在整理之前写的代码和短文,发现挺多有用的东西,也有很多可以合并的东西,还有很多已经失效的东西。很有意思。
在大量代码和少量短文工作之后,感觉好的方法是专注当下的问题和需求,而不是浪费时间和精力在莫名其妙的事情上。
孔子云:“辞达而已矣”。
苏轼又引云:
“所示书教及诗赋杂文,观之熟矣。大略如行云流水,初无定质,但常行于所当行,常止于所不可不止,文理自然,姿态横生。孔子曰:“言之不文,行而不远。”又曰:“辞达而已矣。”夫言止于达意,即疑若不文,是大不然。
好的代码逻辑应该极其自然,像水流一样顺畅。该写逻辑的地方就写(行),逻辑结束了就立刻停住(止),不要为了“看起来像个大系统”而增加冗余的模块和冗长的调用链路。
真正的“辞达”(代码达意)是极难的。要把复杂的业务逻辑在脑中理清楚(了然于心),再用代码精准、高效、简洁地实现出来(了然于口与手),这本身就是最高级的技术水平。能把复杂的逻辑写得让后来者一看就懂,这才是真正的“大牛”。
代码的价值不在于你在 Code Review 时如何舌灿莲花,也不在于你用了多高级的框架。它是否稳定运行了?它是否支撑了性能?它是否省下了成本?它就像金子和玉石,价值是实打实的,不需要靠口舌争辩。为了炫技而增加复杂度的行为,在苏轼(和实用主义程序员)眼里,是毫无价值的。就是典型的“雕虫篆刻”。
编程如此,人生亦然。值得记录下来。
写代码的原则
不要写“好”代码。
写有用的代码,写快的代码,写可靠的代码。
写有价值的代码。
这是一份实用主义编程的宣言。它拒绝将代码视为艺术,而是拥抱代码作为工具的本质。
“好代码”往往是一个陷阱。它是一个充满抽象模式、过早抽象和追求美学完美的学术定义,而这些往往在生产环境的第一次接触中就无法生存(经不起实战考验)。
如果你想写出有用、快速、可靠且有价值的代码,你必须放弃写“好”代码的想法。你需要写有效的代码。
以下是如何将价值置于美德之上的方法。
写“有用”的代码(解决那个该死的问题)
有用的代码不会猜测未来的需求。它解决用户当下的痛点。
YAGNI 是你的信仰(你不需要它 / You Ain't Gonna Need It)。 永远不要为“我们下个季度可能需要”的功能写代码。你这是在浪费今天的时间去解决一个你还没弄明白的问题。如果今天上线不需要它,删掉它。
扼杀抽象。 如果你有一个只有一个实现的接口,删掉该接口。如果你的类层次结构有五层深却只是为了共享两个方法,把它扁平化。抽象本意是为了隐藏复杂性;通常,它们只是制造了复杂性。
先沟通再敲代码。 最有用的代码是你不必写的代码,因为五分钟的对话就能澄清那个需求是愚蠢的。要理解业务目标,而不只是盯着 Jira 工单。
写“快”的代码(速度与性能)
“快”意味着两件事:代码运行得快,以及你写得快。
为了写得快(开发速度):
偷懒(负责任地)。 不要重新发明轮子。如果有一个信誉良好的库能解决问题,就用它。你自己手写的日期选择器实现肯定比标准的要差。我保证。
拥抱“更糟就是更好”。 今天上线的 80% 的解决方案比下个月上线的 100% 的解决方案有价值无数倍。先解决核心情况;只有当边缘情况真正重要时才去处理它们。
复制粘贴没问题。 有时候,复制粘贴一段代码三次,比为了“优雅地”处理这三种情况而发明一个复杂的通用工厂模式更快、更清晰且更容易调试。如果它变成了维护负担,你可以以后再重构(如果真的有必要的话)。
为了让代码运行得快(性能):
问题总是在 I/O(输入/输出)。 如果你的应用很慢,几乎肯定是因为数据库网络调用或磁盘访问。把你 95% 的优化精力集中在那里。
Select N+1 是敌人。 加速应用最快的方法通常是停止为了渲染一个页面而进行 500 次数据库查询。进行预加载(Eager load)。
激进地缓存。 最快的代码是那些从未运行的代码,因为结果已经缓存在内存中了。
写“可靠”的代码(凌晨 3 点也能正常工作)
可靠的代码不是架构完美的;它是假设世界充满敌意的代码。
保持偏执。什么都别信。 来自用户、API 或数据库的每一个输入都可能是恶意的或格式错误的。在边界验证一切。如果数据有误,快速失败并大声报错。
写“笨”代码。 聪明的代码更难理解,更难调试,并且会以意想不到的方式崩溃。写那种简单到明显没有 bug 的代码,而不是那种复杂到看不出明显 bug 的代码。
异常是为异常情况准备的。 不要在标准逻辑流程中使用 try/catch 块。
记录“为什么”,而不仅仅是“什么”。 当东西坏掉时,堆栈跟踪会告诉你哪里出了问题。一条好的日志消息会告诉你系统的状态,以及为什么它最开始要尝试做那件事。
“有价值”的定义
有价值的代码位于这三个特征的交集,但它尊重现实的约束:
价值 = (实用性 × 可靠性) / 上市时间
最有价值的代码往往是丑陋的。它可能有一个巨大的 500 行函数,因为拆分它会让业务逻辑更难跟踪。它可能硬编码了一个配置值,因为将其动态化的努力并不值得。
不要写那种在代码审查中让其他工程师印象深刻的“好”代码。写那种能工作、上线快、并能解决用户问题的有价值的代码。