CppCon 2014 学习: Less Code = More Software
“Less Code = More Software” 是一句简洁而深刻的工程哲学,意思如下:
理解含义
- 更少的代码
→ 并不是功能更少,而是:- 更简洁
- 更清晰
- 更易维护
- 更少 bug
- 更快开发
- 更多的软件
→ 意味着你可以:- 更快交付更多功能
- 更容易扩展系统
- 花更多时间在业务逻辑而非琐碎实现上
本质逻辑
- 每多一行代码,就多一份维护成本
- 每少一层抽象,就多一次重复
- 代码是资产也是负担
示例
多代码风格 | 精简风格 |
---|---|
手写十几个 if-else 分支 | 用策略模式或函数映射表 |
重复复制粘贴的逻辑 | 封装成通用工具函数/模板 |
冗长的类型注册代码 | 用宏+constexpr 注册 GUID |
过度封装导致接口臃肿 | 用少而强的核心接口组合实现复杂功能 |
总结
“Less Code = More Software” 不是说写得越少越好,而是强调:
用更少、更高效的代码,创造更大价值的软件系统。
讨论了软件复杂性的问题,主要观点可以总结如下:
1. 复杂性是软件中最主要的问题之一
- 软件复杂性 被认为是软件开发中最严重、最棘手的问题之一。复杂性往往使得程序难以理解、调试、扩展和维护,甚至影响软件质量和开发效率。
2. 过于复杂的“解决方案”往往容易出现
- 开发者通常更容易写出一种看起来非常复杂的解决方案,而不是去找到一个真正简洁有效的方法来解决问题。
- 这种情形意味着很多时候解决方案的复杂性并非来自于问题本身的本质,而是开发者在设计或实现过程中过度添加了不必要的细节和冗余代码。
3. 大部分软件复杂性是偶然产生的,而非问题本身固有的
- 有“偶然复杂性(accidental complexity)”和“固有复杂性(essential complexity)”之分。
- 固有复杂性是问题本身必然带来的(例如某些高并发、分布式系统中的固有挑战),但大量的软件复杂性则是由于设计不当、代码冗余、滥用抽象、过度工程或其他人为因素引入的。
- 通过良好的架构设计、抽象和重构,可以避免这些“偶然复杂性”。
4. 复杂性往往从细微之处开始,逐步累积
- 复杂性不是一下子冒出来的,而是从每一行代码、每个小决策开始,渐渐堆积而成。
- 每一条不够简单、清晰的语句都可能引入一点潜在的复杂性;而当这些复杂性逐步积累后,就会形成整个系统难以维护和理解的巨大负担。
总结
这段话提醒我们,在软件开发过程中:
- 降低复杂性至关重要:要从一开始就注重代码的简洁与清晰,避免不必要的复杂性。
- 要关注问题的本质:不要为了解决问题而设计出看似“花哨”但实际上臃肿冗余的解决方案。
- 积少成多:细小的复杂性一旦累积,会对整个软件系统产生深远的影响,因此在开发过程中应时刻保持警惕,及时清理、重构代码。
核心思想是强调**“简洁性(Simplicity)”**在软件开发中的重要性。我们逐点来理解:
1. 架构师和开发者必须重视“简洁性”
- 简洁并不意味着功能少,而是以最小的复杂度实现最大的表达能力。
- 简洁的代码更容易理解、测试、维护和扩展。
- 如果一开始不追求简洁,系统就容易变得混乱,未来的改动成本也会急剧上升。
2. 好的抽象(Abstractions)是实现简洁的关键
- 抽象是简化复杂性的工具。一个好的抽象能隐藏细节,让使用者专注于需要的功能,而不是其内部实现。
- 例子:STL 容器、智能指针、接口设计、设计模式等都是抽象的应用。
- 抽象必须恰到好处:抽象太浅会暴露过多细节,太深则可能脱离实际使用。
3. 依赖管理同样重要(Managing Dependencies)
- 依赖过多、耦合过深是复杂性的主要来源。
- 例如:
- 模块之间不清晰的依赖关系;
- 循环依赖;
- 组件耦合紧密,修改一个地方需要改动多个模块。
- 好的依赖管理方法包括:
- 使用接口解耦;
- 依赖倒置原则(DIP);
- 按层架构;
- 使用依赖注入。
4. 要解决更复杂的问题,软件必须更简单
- 这是一个悖论但是真理:越复杂的问题越需要越简单的工具来驾驭。
- 如果软件本身就很复杂,那么当你面对一个复杂业务或系统问题时,将难以应对。
- 比如微服务架构——是为了管理“系统级复杂性”而引入的组织和部署层面的简化,尽管它也带来新的挑战。
5. 构建简单的软件需要经验与技巧,但长期受益巨大
- 简洁的系统往往意味着:
- 更少的 bug;
- 更低的维护成本;
- 更快的开发速度;
- 更高的可测试性和可扩展性。
- 实现简洁不简单,需要:
- 经验;
- 对问题的深入理解;
- 技术选择的权衡;
- 良好的设计习惯。
总结名句(可作为警示):
“简单不是目标。简单是通过了解复杂而达到的结果。”
——Eric Raymond,《Unix 编程艺术》
这几句由 C.A.R. Hoare(托尼·霍尔爵士)提出的名言,反映了他对软件复杂性与简洁性的深刻见解。我们逐句来解析:
1.
“Inside every large program, there is a small program trying to get out.”
“每一个庞大的程序里面,都藏着一个想要逃出来的小程序。”
理解:
- 很多庞大的系统其实是由一组核心功能演变而来的;
- 复杂往往是后期堆叠、补丁、临时解决方案等人为累加的产物;
- 若你能把系统中真正“核心”的部分抽离出来,你就会发现其实它可以很简单;
- 这句话是一种对“精简和重构”的倡导:去发现那个被包裹起来的“小程序”。
2.
“There are two ways of constructing a software design:”
“一种是将它设计得如此简单,以至于明显没有缺陷;”
“另一种是将它设计得如此复杂,以至于没有明显的缺陷。”
“第一种方法要困难得多。”
理解:
- 设计软件有两种思路:
- 极简方案:通过减少功能、明确边界、设计良好接口,使得系统结构清晰、易懂、可维护;
- 复杂方案:表面上看运行良好,但隐藏了很多复杂依赖、不可测试路径或临时修补;
- 第二种方法更容易——只要能跑就行;
- 第一种方法难在:
- 要深入理解问题本质;
- 要做取舍;
- 要反复重构并打磨边界;
- 需要时间和智慧。
精华总结:
简单≠容易,简单=深入理解 + 良好设计 + 克制扩展
为什么这些话重要?
这些格言广泛流传,是因为它们揭示了**“软件本质上的复杂性是人为的”,以及高质量软件需要的智慧不是技术堆砌,而是减法的艺术**。
结合你之前学到的:
- Less Code = More Software
- Simplicity pays off
- Avoid accidental complexity