Files
2026-07-13 13:04:19 +08:00

42 lines
3.8 KiB
Markdown
Raw Permalink Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# 什么是好的代码
好的代码不是"能跑就行",而是在长期演化中保持**压缩性、局部性、可组合性与可证伪性**。
一句话判断:同样的功能,用最小必要的结构实现——概念少,覆盖广,变化不扩散。
---
## 一、模块边界清晰
每个模块只做一件事,依赖方向稳定,指向抽象而非细节。改 A 不需要连带动 B、C、D,没有循环依赖,没有到处互相 import。
## 二、局部可推理
看一个文件、一个函数,就能判断它的行为、代价和失败模式。不需要全局搜索隐式约定、全局状态或魔法配置才能读懂。
## 三、可组合
小组件能自然地组合成大能力,接口一致、正交,不需要为组合写特例。"这个只能在那种情况下用"是坏信号。
## 四、变化半径小
改一个需求,改动集中、可预测,回归风险可控。而不是改动像地震,到处打补丁,回归测试覆盖不了心里的担忧。
## 五、复杂度线性增长
新增一个功能,新增代码量近似线性,重复少。而不是功能越多代码越膨胀,出现大量相似分支和 if-else 森林。
## 六、约束写进代码
关键不变量和约束写进类型、接口、校验、状态机,错误尽早暴露。而不是靠调用者"记得要先做 X 再做 Y",靠注释和口口相传。
## 七、可测试、可观测
依赖可注入,单测容易写,日志和指标能定位因果链。而不是只能端到端测,一出问题就黑盒,难以复现。
## 八、一致且不意外
命名、错误处理、资源管理、并发模型全局一致,很少有反直觉的地方。而不是同一类问题三套解法,新人踩坑全靠运气。
## 九、自解释,注释极简
代码本身就是文档。命名、结构、流程足以说明意图,注释只出现在真正难以一眼看懂或容易误读的地方。如果一段代码需要大段注释才能读懂,说明代码本身该重写。
## 十、代码极简,视觉均匀
行数尽量少,不写多余的代码。每行长度大致平均,避免忽长忽短的锯齿感。简洁不是压缩,是没有废话。
## 十一、函数式倾向,减少副作用
优先纯函数,输入决定输出,减少隐藏的状态突变。但不教条——如果一个全局变量能显著降低整体复杂度,接受它。目标是整体简单,不是局部纯粹。
## 十二、功能越多,代码应该越短
好的抽象让新功能复用已有结构,而不是堆砌新代码。功能翻倍但代码量没怎么涨,说明抽象到位了。反过来,功能越加代码越膨胀,是架构在退化。
## 十三、为未来的接入性设计
写代码时设想:这段逻辑未来会被别的模块调用吗?会被外部系统接入吗?好代码天然留有干净的调用入口,而不是写死在某个特定场景里,等需要复用时才发现得大改。
## 十四、Let it crash——按失败半径决定防御策略
半径大的错误显式报错、快速中断;半径为零的静默放过。不分轻重地到处 try-catch,反而把真正需要暴露的问题吞掉了。
## 十五、篇幅分布跟着功能分布走
一个函数里,主功能占大部分代码,兜底和错误处理压到最短。如果防御性代码比正事还长,说明结构有问题。读代码应该一眼看出主线,而不是在 fallback 里找。
---
## 快速自检
拿到一段代码,问自己四个问题:
1. **我能不能不看全局,就安全地改一个局部?**
2. **有没有一个清晰的核心抽象,让新功能主要是"加新实现"而不是"改旧逻辑"**
3. **变化点是收敛在边界上,还是散落在各处?**
4. **出故障时,能快速定位到责任模块,还是全员背锅?**
四个问题都能干脆地答"是",就是好代码。