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