简约原则:KISS 与奥卡姆剃刀
"如果解释需要更复杂的假设,那它可能就是错的。"
**预计时间:**15 分钟读 + 15 分钟做习题 = 30 分钟。
① KISS 原则 (Keep It Simple, Stupid) 的精确定义;② 奥卡姆剃刀 (Occam's Razor) 的应用方法;③ 如何在工程中识别"过度设计"并简化。
一、什么是 KISS 原则
KISS (Keep It Simple, Stupid) 是一种保持简单、避免过度复杂化的设计原则。
复杂设计:功能多、层级深、耦合紧 → 难维护、难理解
简单设计:功能少、层级浅、耦合松 → 易维护、易理解
"简单 = 好" = 真正的好设计。
芒格说:"真正的好东西是简单的。" 复杂往往是能力不足的体现。
二、KISS vs 过度设计
两种设计思路的对比:
| 维度 | 过度设计 | KISS 原则 |
|---|---|---|
| 功能 | 越多越好 | 够用就好 |
| 层级 | 抽象越多越好 | 必要的抽象 |
| 耦合 | 紧耦合(方便调用) | 松耦合(独立维护) |
| 文档 | 文档越多越好 | 代码即文档 |
| 测试 | 100% 覆盖率 | 关键路径测试 |
1. 过度简化:省掉必要的功能,导致系统不可用
2. 忽视扩展性:为了简单牺牲未来扩展性
3. 忽视可读性:为了简洁牺牲代码可读性
平衡:简单不等于简陋,简约是"必要的复杂度"。
三、奥卡姆剃刀:最简解释
奥卡姆剃刀 (Occam’s Razor) 是一种选择最简解释的思维工具。
复杂解释:需要更多假设、更多条件 → 更可能错
简单解释:需要更少假设、更少条件 → 更可能对
简单解释:"数据库挂了。"
验证:先检查最简单的解释,再逐层深入。
奥卡姆剃刀在工程中的应用
Bug 排查
复杂假设:“可能是并发问题,加上内存泄漏,再加上网络延迟。“
简单假设:“变量名拼错了。“
策略:先检查最简单的解释(语法错误、变量名、边界条件),再考虑复杂问题。
架构设计
复杂架构:微服务 + 事件溯源 + CQRS + 分布式事务
简单架构:单体 + REST API + 数据库事务
策略:如果单体够用,别上微服务。
"简单 = 深度" = 真正的深度。
芒格说:"能用简单方法解决的问题,用复杂方法是愚蠢的。"
四、如何识别”过度设计”
这些信号说明你在过度设计:
- 功能过多:你加了”可能有用”的功能,但用户从未用过
- 层级过深:抽象层超过 3 层,调用链超过 5 步
- 耦合过紧:改一个地方,需要改 5 个地方
- 文档过多:文档比代码还长,但没人看
- 测试过多:测试覆盖率 100%,但关键 bug 还是漏了
public interface UserValidator {
boolean validate(User user);
}
public class UserValidatorImpl implements UserValidator {
private final UserRepository userRepository;
private final EmailValidator emailValidator;
private final PasswordValidator passwordValidator;
public boolean validate(User user) {
return emailValidator.validate(user.getEmail())
&& passwordValidator.validate(user.getPassword())
&& !userRepository.existsByEmail(user.getEmail());
}
}简单设计:public boolean isValidUser(User user) {
return user.getEmail().contains("@")
&& user.getPassword().length() >= 8
&& !userRepository.existsByEmail(user.getEmail());
}结论:第一个版本过度抽象,第二个版本直接、易读。五、练习题
单选题
KISS 原则的核心是?
奥卡姆剃刀的核心是?
系统故障时,奥卡姆剃刀的正确做法是?
"变量名拼错了"属于哪种解释?
"如果单体够用,别上微服务"体现了?
"抽象层超过 3 层"是哪种信号?
KISS 和过度设计的核心区别是?
"文档比代码还长,但没人看"说明?
"测试覆盖率 100%,但关键 bug 还是漏了"说明?
KISS 原则的平衡点是?
案例分析
C1. 案例:团队想引入 GraphQL 替代 REST API,理由是"GraphQL 更灵活"。用 KISS 原则分析,应该先问什么?
C2. 案例:代码审查时发现一个函数有 500 行,用 KISS 原则,应该先考虑什么?
C3. 案例:系统有 3 个抽象层,但只有一种实现,用奥卡姆剃刀分析,最简单的解释是?
反事实思考题
T1. 反事实:如果团队在技术选型时没有用 KISS 原则,选了"最复杂的技术栈",最可能的结果是?
T2. 反事实:如果 bug 排查时没有用奥卡姆剃刀,直接假设是"并发问题",最可能的结果是?
下一步:Lesson 0004 · 安全边际——为什么”够用”比”完美”更重要,以及如何在工程中留出缓冲。