02 Designing Professional C++ Programs

这里先简单阐述下什么是程序设计,为什么这么重要。

简单来说,首先要分析需求,功能需求(functional requirement)就是新的代码要做什么,也可能会有非功能需求(non-functional requirement),描述系统最终什么样子,应该做什么,比如安全、可扩展性、性能指标等。

程序设计(program design)或软件设计(software)描述如何实现功能需求和非功能需求。基本需要包含两个层次。较高层次描述要涉及哪些子系统,这些子系统是如何配合的。较低层次是各个子系统内部是如何实现的。

设计的目的是在写代码之前先思考。

写代码之前先设计,往往不会耽误时间,反而会节省很多时间。如果没有蓝图就盖房子,结果大概率会盖的乱七八糟。写软件也是如此。

C++ 提供了很多范式,比如面向对象、过程式、函数式等,还提供了很多工具来写泛化和可重用的代码,比如模板,同时提供了 STL 库。另外,C++ 很容易与各种设计模式适配。掌握这些对于设计非常重要。

设计不是一蹴而就的,需要反复迭代。给出好的设计很难,不要指望一夜之间变成专家,或许掌握 C++ 设计比 C++ 编码更难。

设计 C++ 程序有两个原则,也适用于其他编程语言:抽象和重用。

抽象(abstraction)将接口(interface)和实现(implementation)分开。要尽可能的对类的使用者屏蔽细节,不要操作底层数据。一般而言,成员变量要 private。好处有 1)可以修改实现而不修改接口;2)可以做一些额外事情,比如检查数据的有效性,返回前做一些转换等;3)更容易 debug。

重用非常重要,比如使用类库就是重用。能够合理利用现有代码是非常重要的能力。

让自己写的代码可以重用,自己能重用自己的类、算法、数据结构。同事能利用自己的组件来实现新功能。设计的时候避免仅仅处理当前的问题。C++ 的模板是写出通用代码的工具。

学习 C++ 编程语言和成为好的 C++ 程序员是两件事情。学习语法和标准只是学习 C++ 本身,还需要大量读他人的代码,写自己的代码,才能成为好的 C++ 程序员。有很多 C++ 最佳实践,这些内容会贯穿这本书。另外,学习一些设计模式、设计技术和框架也是有必要的。

作为一个合格的程序员,要善于利用现有代码。下面先分析使用现有代码的优缺点,然后分析如何选择和确定是否要使用现有代码。另外,利用现有代码不是 copy paste 代码。

重用现有代码有很多好处。无需对这些组件进行详细设计;通常而言无需 debug;对于异常、错误的处理更完善,对各种输入都有校验;类库通常支持不同平台、系统并且都经过了测试;通常是领域专家写的,比如需要加解密功能,直接用类库就无需详细学习密码学相关知识了;类库通常会持续更新,有性能、稳定性提升,使用可以免费获得这些收益。

使用现有类库也会有些许劣势。需要一些时间学习类库接口,怎么正确的使用;类库可能不能提供恰好需求的功能;如果遇到 bug,比较难办,提 bug 让维护者修复,还是自己修复(没有代码就无法这么做了),亦或者是绕开,无法绕开就更难办了;许可证问题;信任维护者;升级新版本可能有问题;升级编译期也可能引入问题。

如何决定呢?如果要写 GUI 程序,那么需要选择 Qt 或者其他类库,大概率不会选择自己实现,但是很多时候比较难决策。下面是一些指导原则。

花一些时间分析类库的能力和局限性;理解学习成本,不仅仅是自己使用的成本,还有其他人甚至新人维护开发的成本;理解性能,即使不是性能关键点也需要理解;考虑平台、系统限制;理解许可证,这点相当重要;调研支持,那么寻求帮助,即使使用公司内部的现有代码,也要考虑这些问题;对于开源软件,维护很重要,是个人项目还是公司项目,是否活跃;C++ 标准库,如果没有特殊理由,比如性能不达标,可以应用尽用。