《代码大全2》读书笔记2

时间:2022-01-13 16:06:57

 

​ 我这周阅读的部分讨论的是怎样组装一个程序。对于程序设计,作者打比方说:构造一个程序就像用原子来造一间房屋,直接从原子开始建造是极其困难的,所以我们需要抽象、需要封装、需要层次、需要复用、需要结构化等等思维工具来帮助我们管理复杂度。由于熵增原理广泛存在于自然界,所以我们还需要一些约定的规范来使得程序更易于维护。例如,一些模块如果散乱地存在于系统中,并且运行他们互相之间进行交流的话,那么整个系统的通信复杂度将变得非常高。作者还提到了一些与编程语言无关的控制复杂度方法,例如隔离容易改变的区域,例如业务规则、外部依赖、输入输出和状态变量等。

​ 作者在写这部分内容时,大都是带着面向对象程序设计的思想去写的,这是一种较为广泛的编程范式,但并不是唯一的编程范式。函数式编程在处理相同的问题时,并不一定遵循作者提到的所有概念。例如,面向对象编程中很强调封装,即类成员变量对外部调用者不可见,但函数式编程中的代数数据类型通常对外部调用者来说是透明的,而且函数也很分散,虽然大部分会集中到同一个包中,但并没有严格的封装。然而令人惊奇的是,这种反封装的编程范式编写出来的代码,却在很多时候比面向对象的系统更可靠,这是值得我们思考的问题。

​ 或许我们需要回到更本质的需求上去,即编程范式需要解决的问题到底是什么。我认为是管理复杂度,这是各种编程范式都在尝试解决的问题。好了,再往上一层,到底哪些思维工具是核心的和必要的呢?首先,代码的复用肯定是一个刚需,因为人的大脑处理信息的能力有限,所以我们需要记忆尽量少的东西来完成尽量多的事情。抽象也是必要的,它是实现代码复用的一个好途径。其次,我认为应对快速变化的业务逻辑也是一个刚需,所以面向对象范式里要求代码低耦合、高内聚,函数式范式里要求函数尽可能简单而且无副作用。信息隐藏或许也有一定的价值,但我认为它的价值不如代码复用和快速迭代。

​ 作者还讨论了一些设计上的细节,例如类中不宜包含超过7个成员变量,继承层次不宜超过3层;除非派生类是一个更特殊的基类,否则不应该继承;要么用继承并进行详细说明,要么不用;共享数据用包含,共享行为用继承;一个类应该尽量少的依赖其他类;工具类应该尽量多地被使用;类的价值:建模、降低复杂度、隐藏实现细节、复用、建立中心控制点;子程序的价值:隐藏执行顺序、复用、管理复杂度;加入一些在开发中方便debug的工具函数,如一段时间检查一下数据完整性等。