作者从抽象的角度描述了程序设计语言的发展,汇编语言是对机器底层的抽象,过程语言是对汇编语言的抽象,这两种语言都是用来描述机器的,而必须由程序员负责建立起问题空间和解空间之间联系的桥梁。
于是人们试图直接在机器上建立问题空间的模型,面向对象语言应运而生。面向对象语言用对象来模拟现实世界中的事物,于是它也就跟现实世界的事物一样,拥有了它需要的各种特性。
在这个大背景下,对象必然拥有自己的类别,于是引入了class的概念。对象要跟外界交互,它的接口便是类的函数。为了控制类的创建者和类的使用者之间的联系,提高模块的独立性,必要的封装是少不了的。
实现代码重用是编程界的重大问题。于是面向对象语言使用组合来重用类的实现,引入继承来重用类的接口。而为了重用类的客户代码,多态就必不可少了。
谈到对象,不免要谈到它的创建和销毁,以控制其生存期和存储区。C++特性的设计目标是效率第一,它灵活多变但比较复杂的内存管理机制便显得理所当然了。意外处理是实际项目中的大问题,标准C++特性在这方面做了大幅度的增强,在语言上保证错误将被处理并且可以恢复正常。
下面作者用很大的篇幅介绍了软件分析和设计的过程。现成的方法都是为了最复杂的情况设计的,我们只需采用一小部分,够用就行。总的来说,作者提倡尽快让程序运行起来,通过简要的分析。
把最重要的部分和风险比较大的部分优先考虑,尽早拿出一个测试版本。当然不是直接开始编码,哪怕再简单的分析也比直接开始编码好得多。但不要过早陷入细节,分析不可能一步到位。
总有些因素要到编码甚至测试阶段才能发现。分析应该做到什么程度呢,对于面向对象编程来说,就是要搞清有哪些对象,它们各有什么接口,你可能需要更多的说明信息,但绝不能再少了。整个过程大概可以分衣五个步骤:
0.制订计划。直接开做也是一种计划,但增加几个里程碑往往更能激励程序员,也多了庆祝的机会。这里用高度抽象的几句话概括整个系统即可,以后觉得不够准确可以改。
1.做什么。即需求分析和系统规范说明。这些文档通常要经过讨论,所以越精简越好。作者建议使用用例,一个用例揭示了系统的一个功能,包括它在各种情况下的反应。用例应该尽量简单,以免过早被一些细节所困扰。接下来,就该制定时间进度表了,尽可能忠实地估算时间,乘以2再加上10%,基本上就可以很好地完成任务了。
2.怎么做。作者建议使用CRC卡,用一张3乘5的卡片,记录一个类的名字、功能及其交互。卡片空间有限,以免过早陷入细节,它让你尽快对系统的全貌有一个初步的认识,也方便讨论。你也可以使用UML。对象的设计一般分为五个阶段:对象的发现、对象的组装、对象的构造、系统的扩充和对象的重用。每个阶段都可能出现新的类,所以不要奢望在这个阶段就提出所有类。对象的开发原则是:一个类只解决一个问题,系统设计的主要任务就是实现需要的类,不要强求一步到位,尽早开始编程,尽量简单。
3.创建内核。只实现让系统运行起来的必要部分和风险比较大的部分,以尽早看到结果。
4.迭代用例。一次迭代增加一个用例,逐步完善。
5.进化。尽善尽美,以备后用。
各种分析和设计方法中最突出的就是极限编程了,很多方法都受它影响,它最重要的两条是先写测试和结对编程。先写测试能强迫程序员给出完整清晰的类接口,还能在每次建立系统时自动测试。从检测的观点来看,程序设计语言的进步就是检测的进步。
汇编语言只能检查到语法错误,C++特性还能检测一些语义上的错误,而面向对象编程语言对主义的检查更为严格。尽管如此,有些错误还是只有运行的时候才能发现,这就需要我们加入一些测试代码来保证程序的正确性。结对编程就是让一个人写代码,另一个人考虑全局,一旦编码无法进行下去,就可以交换过来,再不行还可以让大家一起讨论。
【编辑推荐】