1、2023-1-2412023-1-241第第1010章章 面向对象实现面向对象实现 面向对象实现的主要工作面向对象实现的主要工作 面向对象设计的质量面向对象设计的质量 面向对象测试面向对象测试2023-1-24210.1 10.1 面向对象面向对象语言语言n 10.1.1 10.1.1 面向对象语言的优点面向对象语言的优点n 10.1.2 10.1.2 面向对象语言的技术特点面向对象语言的技术特点n 10.1.3 10.1.3 选择面向对象语言选择面向对象语言2023-1-24310.1.1 10.1.1 面向对象语言的优点面向对象语言的优点 面向对象设计的结果,既可以用面向对象语言,也可以用
2、面向对象设计的结果,既可以用面向对象语言,也可以用非面向对象语言实现。使用面向对象语言时,由于语言本身非面向对象语言实现。使用面向对象语言时,由于语言本身充分支持面向对象概念的实现,因此,编译程序可以自动地充分支持面向对象概念的实现,因此,编译程序可以自动地把面向对象概念映射到目标程序中。使用非面向对象语言编把面向对象概念映射到目标程序中。使用非面向对象语言编写面向对象程序,则必须由程序员自己把面向对象概念映射写面向对象程序,则必须由程序员自己把面向对象概念映射到目标程序中。到目标程序中。2023-1-24410.1.1 10.1.1 面向对象语言的优点面向对象语言的优点 到底应该选用面向对象
3、语言还是非面向对象语言,关键不到底应该选用面向对象语言还是非面向对象语言,关键不在于语言功能强弱。选择编程语言的关键因素,是语言的一致在于语言功能强弱。选择编程语言的关键因素,是语言的一致的表达能力、可重用性及可维护性。从面向对象观点看来,能的表达能力、可重用性及可维护性。从面向对象观点看来,能够更完整、更准确地表达问题域语义的面向对象语言的语法是够更完整、更准确地表达问题域语义的面向对象语言的语法是非常重要的,因为这会带来下述几个重要优点。非常重要的,因为这会带来下述几个重要优点。2023-1-24510.1.1 10.1.1 面向对象语言的优点面向对象语言的优点n 1 1一致的表示方法一致
4、的表示方法 从前面章节的讲述中可以知道,面向对象开发基于不随时从前面章节的讲述中可以知道,面向对象开发基于不随时间变化的、一致的表示方法。这种表示方法应该从问题域到间变化的、一致的表示方法。这种表示方法应该从问题域到OOAOOA,从,从OOAOOA到到OODOOD,最后从,最后从OODOOD到面向对象编程到面向对象编程(OOPOOP),始终稳定不变。一致的表示方法既有利于在软件),始终稳定不变。一致的表示方法既有利于在软件开发过程中始终使用统一的概念,也有利于维护人员理解软件开发过程中始终使用统一的概念,也有利于维护人员理解软件的各种配置成分。的各种配置成分。2023-1-24610.1.1
5、10.1.1 面向对象语言的优点面向对象语言的优点n 2 2可重用性可重用性 为了能带来可观的商业利益,必须在更广泛的范围中运用为了能带来可观的商业利益,必须在更广泛的范围中运用重用机制,而不是仅仅在程序设计这个层次上进行重用。因此,重用机制,而不是仅仅在程序设计这个层次上进行重用。因此,在在OOAOOA、OODOOD直到直到OOPOOP中都显式地表示问题域语义,其意义中都显式地表示问题域语义,其意义是十分深远的。随着时间的推移,软件开发组织既可能重用它是十分深远的。随着时间的推移,软件开发组织既可能重用它在某个问题域内的在某个问题域内的OOAOOA结果,也可能重用相应的结果,也可能重用相应的
6、OODOOD和和OOPOOP结果。结果。2023-1-24710.1.1 10.1.1 面向对象语言的优点面向对象语言的优点n 3 3可维护性可维护性 尽管人们反复强调保持文档与源程序一致的必要性,但是,尽管人们反复强调保持文档与源程序一致的必要性,但是,在实际工作中很难做到交付两类不同的文档,并使它们保持彼此在实际工作中很难做到交付两类不同的文档,并使它们保持彼此完全一致。特别是考虑到进度、预算、能力、人员等限制因素时,完全一致。特别是考虑到进度、预算、能力、人员等限制因素时,做到两类文档完全一致几乎是不可能的。因此,维护人员最终面做到两类文档完全一致几乎是不可能的。因此,维护人员最终面对的
7、往往只有源程序本身对的往往只有源程序本身。2023-1-24810.1.2 10.1.2 面向对象语言的技术特点面向对象语言的技术特点 一般说来,纯面向对象语言着重支持面向对象方法研一般说来,纯面向对象语言着重支持面向对象方法研究和快速原型的实现,而混合型面向对象语言的目标则是究和快速原型的实现,而混合型面向对象语言的目标则是提高运行速度和使传统程序员容易接受面向对象思想。成提高运行速度和使传统程序员容易接受面向对象思想。成熟的面向对象语言通常都提供丰富的类库和强有力的开发熟的面向对象语言通常都提供丰富的类库和强有力的开发环境。环境。2023-1-24910.1.2 10.1.2 面向对象语言
8、的技术特点面向对象语言的技术特点n 1 1支持类与对象概念的机制支持类与对象概念的机制 所有面向对象语言都允许用户动态创建对象,并且可以用指所有面向对象语言都允许用户动态创建对象,并且可以用指针引用动态创建的对象。允许动态创建对象,就意味着系统必须针引用动态创建的对象。允许动态创建对象,就意味着系统必须处理内存管理问题。有两种管理内存的方法:一种是由语言的运处理内存管理问题。有两种管理内存的方法:一种是由语言的运行机制自动管理内存,即提供自动回收行机制自动管理内存,即提供自动回收“垃圾垃圾”的机制;另一种的机制;另一种是由程序员编写释放内存的代码。是由程序员编写释放内存的代码。2023-1-2
9、41010.1.2 10.1.2 面向对象语言的技术特点面向对象语言的技术特点 自动管理内存不仅方便而且安全,但是必须采用先进的自动管理内存不仅方便而且安全,但是必须采用先进的垃圾收集算法才能减少开销。某些面向对象的语言(如垃圾收集算法才能减少开销。某些面向对象的语言(如C+C+)允许程序员定义析构函数(允许程序员定义析构函数(destructordestructor)。每当一个对象)。每当一个对象超出范围或被显式删除时,就自动调用析构函数。这种机制超出范围或被显式删除时,就自动调用析构函数。这种机制使得程序员能够方便地构造和唤醒释放内存的操作,却又不使得程序员能够方便地构造和唤醒释放内存的操
10、作,却又不是垃圾收集机制。是垃圾收集机制。2023-1-241110.1.2 10.1.2 面向对象语言的技术特点面向对象语言的技术特点n 2 2实现整体一部分结构的机制实现整体一部分结构的机制 一般说来,有两种实现方法,分别使用指针和独立的关联一般说来,有两种实现方法,分别使用指针和独立的关联对象实现整体一部分结构。大多数现有的面向对象语言并不显对象实现整体一部分结构。大多数现有的面向对象语言并不显式支持独立的关联对象,在这种情况下,使用指针是最容易的式支持独立的关联对象,在这种情况下,使用指针是最容易的实现方法,通过增加内部指针可以方便地实现关联。实现方法,通过增加内部指针可以方便地实现关
11、联。2023-1-241210.1.2 10.1.2 面向对象语言的技术特点面向对象语言的技术特点n 3 3实现一般一特殊结实现一般一特殊结 这里既包括实现继承的机制也包括解决名字冲突的机制。这里既包括实现继承的机制也包括解决名字冲突的机制。所谓解决名字冲突,指的是处理在多个基类中可能出现的重名所谓解决名字冲突,指的是处理在多个基类中可能出现的重名问题,这个问题仅在支持多重继承的语言中才会遇到。某些语问题,这个问题仅在支持多重继承的语言中才会遇到。某些语言拒绝接受有名字冲突的程序,另一些语言提供了解决冲突的言拒绝接受有名字冲突的程序,另一些语言提供了解决冲突的协议。不论使用何种语言,程序员都应
12、该尽力避免出现名字冲协议。不论使用何种语言,程序员都应该尽力避免出现名字冲突。突。2023-1-241310.1.2 10.1.2 面向对象语言的技术特点面向对象语言的技术特点n 4 4实现属性和服务的机制实现属性和服务的机制 对于实现属性的机制应该着重考虑以下几个方面:支持对于实现属性的机制应该着重考虑以下几个方面:支持实例连接的机制;属性的可见性控制;对属性值的约束。对实例连接的机制;属性的可见性控制;对属性值的约束。对于服务来说,主要应该考虑下列因素:支持消息连接(即表于服务来说,主要应该考虑下列因素:支持消息连接(即表达对象交互关系)的机制;控制服务可见性的机制;动态联达对象交互关系)
13、的机制;控制服务可见性的机制;动态联编。编。2023-1-241410.1.2 10.1.2 面向对象语言的技术特点面向对象语言的技术特点 所谓动态联编,是指应用系统在运行过程中,当需要执所谓动态联编,是指应用系统在运行过程中,当需要执行一个特定服务的时候,选择(或联编)实现该服务的适当行一个特定服务的时候,选择(或联编)实现该服务的适当算法的能力。动态联编机制使得程序员在向对象发送消息时算法的能力。动态联编机制使得程序员在向对象发送消息时拥有较大自由,在发送消息前,无须知道接受消息的对象当拥有较大自由,在发送消息前,无须知道接受消息的对象当时属于哪个类。时属于哪个类。2023-1-24151
14、0.1.2 10.1.2 面向对象语言的技术特点面向对象语言的技术特点n 5 5类型检查类型检查 程序设计语言可以按照编译时进行类型检查的严格程度来程序设计语言可以按照编译时进行类型检查的严格程度来分类。如果语言仅要求每个变量或属性隶属于一个对象,则是分类。如果语言仅要求每个变量或属性隶属于一个对象,则是弱类型的;如果语法规定每个变量或属性必须准确地属于某个弱类型的;如果语法规定每个变量或属性必须准确地属于某个特定的类,则这样的语言是强类型的。面向对象语言在这方面特定的类,则这样的语言是强类型的。面向对象语言在这方面差异很大。差异很大。2023-1-241610.1.2 10.1.2 面向对象
15、语言的技术特点面向对象语言的技术特点 强类型语言主要有两个优点:一是有利于在编译时发强类型语言主要有两个优点:一是有利于在编译时发现程序错误,二是增加了优化的可能性。通常使用强类型现程序错误,二是增加了优化的可能性。通常使用强类型编译型语言开发软件产品,使用弱类型解释型语言快速开编译型语言开发软件产品,使用弱类型解释型语言快速开发原型。总的来说,强类型语言有助于提高软件的可靠性发原型。总的来说,强类型语言有助于提高软件的可靠性和运行效率,现代的程序语言理论支持强类型检查,大多和运行效率,现代的程序语言理论支持强类型检查,大多数新语言都是强类型的。数新语言都是强类型的。2023-1-241710
16、.1.2 10.1.2 面向对象语言的技术特点面向对象语言的技术特点n 6 6类库大多数面向对象语言都提供一个实用的类库类库大多数面向对象语言都提供一个实用的类库 某些语言本身并没有规定提供什么样的类库,而是由实现这种某些语言本身并没有规定提供什么样的类库,而是由实现这种语言的编译系统自行提供类库。存在类库,许多软构件就不必由程语言的编译系统自行提供类库。存在类库,许多软构件就不必由程序员重头编写了,这为实现软件重用带来很大方便。序员重头编写了,这为实现软件重用带来很大方便。2023-1-241810.1.2 10.1.2 面向对象语言的技术特点面向对象语言的技术特点n 7 7效率效率 事实上
17、,使用拥有完整类库的面向对象语言,有时能比使用事实上,使用拥有完整类库的面向对象语言,有时能比使用非面向对象语言得到运行更快的代码,这是因为类库中提供了更非面向对象语言得到运行更快的代码,这是因为类库中提供了更高效的算法和更好的数据结构。例如,程序员已经无须编写实现高效的算法和更好的数据结构。例如,程序员已经无须编写实现哈希表或平衡树算法的代码了,类库中已经提供了这类数据结构,哈希表或平衡树算法的代码了,类库中已经提供了这类数据结构,而且算法先进、代码精巧可靠。而且算法先进、代码精巧可靠。2023-1-241910.1.2 10.1.2 面向对象语言的技术特点面向对象语言的技术特点 一些面向对
18、象语言(如一些面向对象语言(如C+C+),没有提供直接存储对象的机),没有提供直接存储对象的机制。这些语言的用户必须自己管理对象的输入制。这些语言的用户必须自己管理对象的输入/输出,或者购买面输出,或者购买面向对象的数据库管理系统。向对象的数据库管理系统。另外一些面向对象语言(如另外一些面向对象语言(如SmalltalkSmalltalk),把当前的执行状态),把当前的执行状态完整地保存在磁盘上。还有一些面向对象语言,提供了访问磁盘完整地保存在磁盘上。还有一些面向对象语言,提供了访问磁盘对象的输入对象的输入/输出操作。输出操作。2023-1-242010.1.2 10.1.2 面向对象语言的技
19、术特点面向对象语言的技术特点 通过在类库中增加对象存储管理功能,可以在不改变通过在类库中增加对象存储管理功能,可以在不改变语言定义或不增加关键字的情况下,就在开发环境中提供语言定义或不增加关键字的情况下,就在开发环境中提供这种功能。然后,可以从这种功能。然后,可以从“可存储的类可存储的类”中派生出需要持中派生出需要持久保存的对象,该对象自然继承了对象存储管理功能。这久保存的对象,该对象自然继承了对象存储管理功能。这就是就是EiffelEiffel语言采用的策略。理想情况下,应该使程序设计语言采用的策略。理想情况下,应该使程序设计语言语法与对象存储管理语法实现无缝集成。语言语法与对象存储管理语法
20、实现无缝集成。2023-1-242110.1.2 10.1.2 面向对象语言的技术特点面向对象语言的技术特点n 9 9参数化类参数化类 所谓参数化类,就是使用一个或多个类型去参数化一个类所谓参数化类,就是使用一个或多个类型去参数化一个类的机制。有了这种机制,程序员就可以先定义一个参数化的类模的机制。有了这种机制,程序员就可以先定义一个参数化的类模板(即在类定义中包含以参数形式出现的一个或多个类型),然板(即在类定义中包含以参数形式出现的一个或多个类型),然后把数据类型作为参数传递进来,从而把这个类模板应用在不同后把数据类型作为参数传递进来,从而把这个类模板应用在不同的应用程序中,或用在同一应用
21、程序的不同部分。的应用程序中,或用在同一应用程序的不同部分。2023-1-242210.1.2 10.1.2 面向对象语言的技术特点面向对象语言的技术特点n 1010开发环境软件工具和软件工程环境对软件生开发环境软件工具和软件工程环境对软件生产率有很大影响产率有很大影响 由于面向对象程序中继承关系和动态联编等引入的特殊复杂由于面向对象程序中继承关系和动态联编等引入的特殊复杂性,面向对象语言所提供的软件工具或开发环境就显得尤其重要性,面向对象语言所提供的软件工具或开发环境就显得尤其重要了。了。至少应该包括下列一些最基本的软件工具:编辑程序、编译至少应该包括下列一些最基本的软件工具:编辑程序、编译
22、程序或解释程序、浏览工具、调试器(程序或解释程序、浏览工具、调试器(debuggerdebugger)等。)等。2023-1-242310.1.3 10.1.3 选择面向对象语言选择面向对象语言n 1 1选择选择将来能否占主导地位将来能否占主导地位的语言的语言 根据目前占有的市场份额,以及专业书刊和学术会议上所做根据目前占有的市场份额,以及专业书刊和学术会议上所做的分析、评价,人们往往能够对未来哪种面向对象语言将占据主的分析、评价,人们往往能够对未来哪种面向对象语言将占据主导地位做出预测。导地位做出预测。但是,最终决定选用哪种面向对象语言的实际因素,往往是但是,最终决定选用哪种面向对象语言的实
23、际因素,往往是诸如成本之类的经济因素而不是技术因素。诸如成本之类的经济因素而不是技术因素。2023-1-242410.1.3 10.1.3 选择面向对象语言选择面向对象语言n 2 2考虑具有良好考虑具有良好类库和开发环境类库和开发环境的语言的语言 语言、开发环境和类库这语言、开发环境和类库这3 3个因素综合起来,共同决定了可个因素综合起来,共同决定了可重用性。考虑类库的时候,不仅应该考虑是否提供了类库,还应重用性。考虑类库的时候,不仅应该考虑是否提供了类库,还应该考虑类库中提供了哪些有价值的类。随着类库的日益成熟和丰该考虑类库中提供了哪些有价值的类。随着类库的日益成熟和丰富,在开发新应用系统时
24、,需要开发人员自己编写的代码将越来富,在开发新应用系统时,需要开发人员自己编写的代码将越来越少。越少。2023-1-242510.1.3 10.1.3 选择面向对象语言选择面向对象语言n 3 3考虑考虑其他因素其他因素 在选择编程语言时,应该考虑的其他因素还有:对用户学习在选择编程语言时,应该考虑的其他因素还有:对用户学习面向对象分析、设计和编码技术所能提供的培训服务;在使用这面向对象分析、设计和编码技术所能提供的培训服务;在使用这个面向对象语言期间能提供的技术支持;能提供给开发人员使用个面向对象语言期间能提供的技术支持;能提供给开发人员使用的开发工具、开发平台和发行平台,对机器性能和内存的需
25、求,的开发工具、开发平台和发行平台,对机器性能和内存的需求,集成已有软件的容易程度等。集成已有软件的容易程度等。2023-1-242610.2 10.2 面向对象面向对象程序设计风格程序设计风格n 10.2.1 10.2.1 提高可重用性提高可重用性n 10.2.2 10.2.2 提高可扩充性提高可扩充性n 10.2.3 10.2.3 提高健壮性提高健壮性2023-1-242710.2.1 10.2.1 提高可重用性提高可重用性 面向对象方法的一个主要目标,就是提高软件的可面向对象方法的一个主要目标,就是提高软件的可重用性。软件重用有多个层次,在编码阶段主要考虑代重用性。软件重用有多个层次,在
26、编码阶段主要考虑代码重用的问题。一般说来,代码重用有两种:一种是本码重用的问题。一般说来,代码重用有两种:一种是本项目内的代码重用,另一种是新项目重用旧项目的代码。项目内的代码重用,另一种是新项目重用旧项目的代码。2023-1-242810.2.1 10.2.1 提高可重用性提高可重用性 内部重用主要是找出设计中相同或相似的部分,然后利内部重用主要是找出设计中相同或相似的部分,然后利用继承机制共享它们。为做到外部重用(即一个项目重用另用继承机制共享它们。为做到外部重用(即一个项目重用另一项目的代码),必须有长远眼光,需要反复考虑、精心设一项目的代码),必须有长远眼光,需要反复考虑、精心设计。虽
27、然为实现外部重用所需要考虑的面,比为实现内部重计。虽然为实现外部重用所需要考虑的面,比为实现内部重用而需要考虑的面更广,但是,有助于实现这两类重用的程用而需要考虑的面更广,但是,有助于实现这两类重用的程序设计准则却是相同的。序设计准则却是相同的。2023-1-242910.2.1 10.2.1 提高可重用性提高可重用性n 1 1提高方法的内聚提高方法的内聚 一个方法(即服务)应该只完成单个功能。如果某个方一个方法(即服务)应该只完成单个功能。如果某个方法涉及两个或多个不相关的功能,则应该把它分解成几个更法涉及两个或多个不相关的功能,则应该把它分解成几个更小的方法。小的方法。2023-1-243
28、010.2.1 10.2.1 提高可重用性提高可重用性n 2 2减小方法的规模减小方法的规模 应该减小方法的规模,如果某个方法规模过大(代码长度应该减小方法的规模,如果某个方法规模过大(代码长度超过一页纸可能就太大了),则应该把它分解成几个更小的方超过一页纸可能就太大了),则应该把它分解成几个更小的方法。法。2023-1-243110.2.1 10.2.1 提高可重用性提高可重用性n 3 3保持方法的一致性保持方法的一致性 保持方法的一致性,有助于实现代码重用。一般来说,保持方法的一致性,有助于实现代码重用。一般来说,功能相似的方法应该有一致的名字、参数特征(包括参数功能相似的方法应该有一致的
29、名字、参数特征(包括参数个数、类型和次序)、返回值类型、使用条件、出错条件个数、类型和次序)、返回值类型、使用条件、出错条件等。等。2023-1-243210.2.1 10.2.1 提高可重用性提高可重用性n 4 4把策略与实现分开把策略与实现分开 从所完成的功能看,有两种不同类型的方法:一类方法负从所完成的功能看,有两种不同类型的方法:一类方法负责做出决策,提供变元,并且管理全局资源,可称为策略方法;责做出决策,提供变元,并且管理全局资源,可称为策略方法;另一类方法负责完成具体的操作,但却并不做出是否执行这个另一类方法负责完成具体的操作,但却并不做出是否执行这个操作的决定,也不知道为什么执行
30、这个操作,可称为实现方法。操作的决定,也不知道为什么执行这个操作,可称为实现方法。2023-1-243310.2.1 10.2.1 提高可重用性提高可重用性 策略方法应该检查系统运行状态,并处理出错情况,策略方法应该检查系统运行状态,并处理出错情况,它们并不直接完成计算或实现复杂的算法。策略方法通它们并不直接完成计算或实现复杂的算法。策略方法通常紧密依赖于具体应用,这类方法比较容易编写,也比常紧密依赖于具体应用,这类方法比较容易编写,也比较容易理解。较容易理解。2023-1-243410.2.1 10.2.1 提高可重用性提高可重用性n 5 5全面覆盖全面覆盖 如果输入条件的各种组合都可能出现
31、,则应该针对所有组如果输入条件的各种组合都可能出现,则应该针对所有组合写出方法,而不能仅仅针对当前用到的组合情况写方法。例合写出方法,而不能仅仅针对当前用到的组合情况写方法。例如,如果在当前应用中需要写一个方法,以获取表中第一个元如,如果在当前应用中需要写一个方法,以获取表中第一个元素,则至少还应该为获取表中最后一个元素再写一个方法。素,则至少还应该为获取表中最后一个元素再写一个方法。2023-1-243510.2.1 10.2.1 提高可重用性提高可重用性n 6 6尽量不使用全局信息尽量不使用全局信息 应该尽量降低方法与外界的耦合程度,不使用全局信息是应该尽量降低方法与外界的耦合程度,不使用
32、全局信息是降低耦合度的一项主要措施。降低耦合度的一项主要措施。2023-1-243610.2.1 10.2.1 提高可重用性提高可重用性n 7 7利用继承机制利用继承机制 在面向对象程序中,使用继承机制是实现共享和提高重在面向对象程序中,使用继承机制是实现共享和提高重用程度的主要途径用程度的主要途径。2023-1-243710.2.1 10.2.1 提高可重用性提高可重用性(1 1)调用子)调用子过程过程 最最简单的做法是把公共的代码分离出来,构成一个被其他方简单的做法是把公共的代码分离出来,构成一个被其他方法调用的公用方法。可以在基类中定义这个公用方法,供派生类法调用的公用方法。可以在基类中
33、定义这个公用方法,供派生类中的方法调用中的方法调用。2023-1-243810.2.1 10.2.1 提高可重用性提高可重用性(2 2)分解)分解因子因子 有时有时提高相似类代码可重用性的一个有效途径,是从不同类提高相似类代码可重用性的一个有效途径,是从不同类的相似方法中分解出不同的的相似方法中分解出不同的“因子因子”(即不同的代码),把余下(即不同的代码),把余下的代码作为公用方法中的公共代码,把分解出的因子作为名字相的代码作为公用方法中的公共代码,把分解出的因子作为名字相同算法不同的方法,放在不同类中定义,并被这个公用方法调用同算法不同的方法,放在不同类中定义,并被这个公用方法调用。202
34、3-1-243910.2.1 10.2.1 提高可重用性提高可重用性 使用这种途径通常额外定义一个抽象基类,并在这个抽象使用这种途径通常额外定义一个抽象基类,并在这个抽象基类中定义公用方法。把这种途径与面向对象语言提供的多态基类中定义公用方法。把这种途径与面向对象语言提供的多态性机制结合起来,让派生类继承抽象基类中定义的公用方法,性机制结合起来,让派生类继承抽象基类中定义的公用方法,可以明显降低为增添新子类而需付出的工作量,因为只需在新可以明显降低为增添新子类而需付出的工作量,因为只需在新子类中编写其特有的代码。子类中编写其特有的代码。2023-1-244010.2.1 10.2.1 提高可重
35、用性提高可重用性(3 3)把代码封装在类中)把代码封装在类中 程序员往往希望重用用其他方法编写的、解决同一类应用问程序员往往希望重用用其他方法编写的、解决同一类应用问题的程序代码。重用这类代码的一个比较安全的途径,是把被重题的程序代码。重用这类代码的一个比较安全的途径,是把被重用的代码封装在类中。用的代码封装在类中。2023-1-244110.2.2 10.2.2 提高可扩充性提高可扩充性n 1 1封装实现策略封装实现策略 应该把类的实现策略(包括描述属性的数据结构、修改属应该把类的实现策略(包括描述属性的数据结构、修改属性的算法等)封装起来,对外只提供公有的接口,否则将降低性的算法等)封装起
36、来,对外只提供公有的接口,否则将降低今后修改数据结构或算法的自由度。今后修改数据结构或算法的自由度。2023-1-244210.2.2 10.2.2 提高可扩充性提高可扩充性n 2 2慎用慎用公有方法公有方法 公有方法是向公众公布的接口。为提高可修改性,降低维公有方法是向公众公布的接口。为提高可修改性,降低维护成本,必须精心选择和定义公有方法。私有方法是仅在类内护成本,必须精心选择和定义公有方法。私有方法是仅在类内使用的方法,通常利用私有方法来实现公有方法。删除、增加使用的方法,通常利用私有方法来实现公有方法。删除、增加或修改私有方法所涉及的面要窄得多,因此代价也比较低。或修改私有方法所涉及的
37、面要窄得多,因此代价也比较低。2023-1-244310.2.2 10.2.2 提高可扩充性提高可扩充性n 3 3不要用一个方法遍历多条关联链不要用一个方法遍历多条关联链 一个方法应该只包含对象模型中的有限内容。违反这条准一个方法应该只包含对象模型中的有限内容。违反这条准则将导致方法过分复杂,既不易理解,也不易修改扩充。则将导致方法过分复杂,既不易理解,也不易修改扩充。2023-1-244410.2.2 10.2.2 提高可扩充性提高可扩充性n 4 4避免使用多分支语句避免使用多分支语句 一般说来,可以利用一般说来,可以利用DO-CASEDO-CASE语句测试对象的内部状语句测试对象的内部状态
38、,而不要用来根据对象类型选择应有的行为,否则在增添态,而不要用来根据对象类型选择应有的行为,否则在增添新类时将不得不修改原有的代码。应该合理地利用多态性机新类时将不得不修改原有的代码。应该合理地利用多态性机制,根据对象当前类型,自动决定应有的行为。制,根据对象当前类型,自动决定应有的行为。2023-1-244510.2.3 10.2.3 提高健壮性提高健壮性 程序员在编写实现方法的代码时,既应该考虑效率,也程序员在编写实现方法的代码时,既应该考虑效率,也应该考虑健壮性。通常需要在健壮性与效率之间做出适当的折应该考虑健壮性。通常需要在健壮性与效率之间做出适当的折中。必须认识到,对于任何一个实用软
39、件来说,健壮性都是不中。必须认识到,对于任何一个实用软件来说,健壮性都是不可忽略的质量指标。为提高健壮性应该遵守以下几条准则。可忽略的质量指标。为提高健壮性应该遵守以下几条准则。2023-1-244610.2.3 10.2.3 提高健壮性提高健壮性n 1 1具备处理具备处理用户操作错误用户操作错误的能力的能力 软件系统必须具有处理用户操作错误的能力。当用户在输软件系统必须具有处理用户操作错误的能力。当用户在输入数据时发生错误,不应该引起程序运行中断,更不应该造入数据时发生错误,不应该引起程序运行中断,更不应该造成成“死机死机”。任何一个接收用户输入数据的方法,对其接收。任何一个接收用户输入数据
40、的方法,对其接收到的数据必须进行检查,即使发现了非常严重的错误,也应到的数据必须进行检查,即使发现了非常严重的错误,也应该给出恰当的提示信息,并准备再次接收用户的输入。该给出恰当的提示信息,并准备再次接收用户的输入。2023-1-244710.2.3 10.2.3 提高健壮性提高健壮性n 2 2检查参数的合法性检查参数的合法性 对公有方法,尤其应该着重检查其参数的合法性,因为用对公有方法,尤其应该着重检查其参数的合法性,因为用户在使用公有方法时可能违反参数的约束条件。户在使用公有方法时可能违反参数的约束条件。2023-1-244810.2.3 10.2.3 提高健壮性提高健壮性n 3 3不要预
41、先确定限制条件不要预先确定限制条件 在设计阶段,往往很难准确地预测出应用系统中使用的数在设计阶段,往往很难准确地预测出应用系统中使用的数据结构的最大容量需求。因此不应该预先设定限制条件。如据结构的最大容量需求。因此不应该预先设定限制条件。如果有必要和可能,则应该使用动态内存分配机制,创建未预果有必要和可能,则应该使用动态内存分配机制,创建未预先设定限制条件的数据结构。先设定限制条件的数据结构。2023-1-244910.2.3 10.2.3 提高健壮性提高健壮性n 4 4先测试后优化先测试后优化 为在效率与健壮性之间做出合理的折中,应该在为提高效为在效率与健壮性之间做出合理的折中,应该在为提高
42、效率而进行优化之前,先测试程序的性能。经过测试,合理地确率而进行优化之前,先测试程序的性能。经过测试,合理地确定为提高性能应该着重优化的关键部分。如果实现某个操作的定为提高性能应该着重优化的关键部分。如果实现某个操作的算法有许多种,则应该综合考虑内存需求、速度、实现的简易算法有许多种,则应该综合考虑内存需求、速度、实现的简易程度等因素,经合理折中选定适当的算法。程度等因素,经合理折中选定适当的算法。2023-1-245010.3 10.3 测测 试试 策策 略略10.3.1 10.3.1 面向对象测试模型面向对象测试模型 面向对象的开发模型突破了传统的瀑布模型,将开发分为面向面向对象的开发模型
43、突破了传统的瀑布模型,将开发分为面向对象分析对象分析(OOA)(OOA),面向对象设计,面向对象设计(OOD)(OOD)和面向对象编程和面向对象编程(OOP)(OOP)三个三个阶段。针对这种开发模型,结合传统的测试步骤的划分,把面向对阶段。针对这种开发模型,结合传统的测试步骤的划分,把面向对象的软件测试分为:面向对象分析的测试、面向对象设计的测试、象的软件测试分为:面向对象分析的测试、面向对象设计的测试、面向对象编程的测试、面向对象单元测试、面向对象集成测试、面面向对象编程的测试、面向对象单元测试、面向对象集成测试、面向对象系统测试。向对象系统测试。2023-1-245110.3.2 10.3
44、.2 面向对象分析的测试面向对象分析的测试(1)(1)对认定的对象的测试。对认定的对象的测试。(2)(2)对认定的结构的测试。对认定的结构的测试。(3)(3)对认定的主题的测试。对认定的主题的测试。(4)(4)对定义的属性和实例关联的测试。对定义的属性和实例关联的测试。(5)(5)对定义的服务和消息关联的测试。对定义的服务和消息关联的测试。2023-1-245210.3.3 10.3.3 面向对象设计的测试面向对象设计的测试 对对OODOOD的测试,应从如下三方面考虑:对认定的的测试,应从如下三方面考虑:对认定的类的测试;对构造的类层次结构的测试;对类库的支类的测试;对构造的类层次结构的测试;
45、对类库的支持的测试。持的测试。2023-1-245310.3.4 10.3.4 面向对象编程的测试面向对象编程的测试 在在面向对象编程面向对象编程(OOP)(OOP)阶段,忽略类功能实现的细则,阶段,忽略类功能实现的细则,将测试的目光集中在类功能的实现和相应的面向对象程序风将测试的目光集中在类功能的实现和相应的面向对象程序风格,主要体现为以下两个方面。格,主要体现为以下两个方面。(1)(1)数据成员是否满足数据封装的要求。数据成员是否满足数据封装的要求。(2)(2)类是否实现了要求的功能。类是否实现了要求的功能。2023-1-245410.3.5 10.3.5 面向对象的单元测试面向对象的单元
46、测试 “封装封装”导致了类和对象的定义,这意味着类和类的实例导致了类和对象的定义,这意味着类和类的实例(对象)包装了属性(数据)和处理这些数据的操作(也称为(对象)包装了属性(数据)和处理这些数据的操作(也称为方法或服务)。现在,最小的可测试单元是封装起来的类和对方法或服务)。现在,最小的可测试单元是封装起来的类和对象。一个类可以包含一组不同的操作,而一个特定的操作也可象。一个类可以包含一组不同的操作,而一个特定的操作也可能存在于一组不同的类中。因此,对于面向对象的软件来说,能存在于一组不同的类中。因此,对于面向对象的软件来说,单元测试的含义发生了很大变化。单元测试的含义发生了很大变化。202
47、3-1-245510.3.5 10.3.5 面向对象的单元测试面向对象的单元测试 不能再孤立地测试单个操作,而应该把操作作为类的一部分不能再孤立地测试单个操作,而应该把操作作为类的一部分来测试。让我们举例说明上述论点:考虑一个类层次,操作来测试。让我们举例说明上述论点:考虑一个类层次,操作X X在超在超类中定义并被一组子类继承,每个子类都使用操作类中定义并被一组子类继承,每个子类都使用操作X X,但是,但是,X X调调用子类中定义的操作并处理子类的私有属性。用子类中定义的操作并处理子类的私有属性。2023-1-245610.3.5 10.3.5 面向对象的单元测试面向对象的单元测试 由于在不同
48、的子类中使用操作由于在不同的子类中使用操作X X的环境有微妙的不同,因此的环境有微妙的不同,因此有必要在每个子类的语境中测试操作有必要在每个子类的语境中测试操作X X。这就意味着,当测试面向。这就意味着,当测试面向对象软件时,传统的单元测试方法是无效的,我们不能再在对象软件时,传统的单元测试方法是无效的,我们不能再在“真真空空”中(即孤立地)测试操作中(即孤立地)测试操作X X。2023-1-245710.3.6 10.3.6 面向对象的集成测试面向对象的集成测试 因为在面向对象的软件中不存在层次的控制结构,传统的自因为在面向对象的软件中不存在层次的控制结构,传统的自顶向下和自底向上的集成策略
49、就没有意义了。此外,由于构成类顶向下和自底向上的集成策略就没有意义了。此外,由于构成类的成分彼此间存在直接或间接的交互,一次集成一个操作到类中的成分彼此间存在直接或间接的交互,一次集成一个操作到类中(传统的渐增式集成方法),通常是不可能的。(传统的渐增式集成方法),通常是不可能的。2023-1-245810.3.7 10.3.7 面向对象的面向对象的系统测试系统测试1)1)应当尽早和不断地测试。应当尽早和不断地测试。2)2)程序员应避免检查自己的程序,测试工作应该由独立的专业的程序员应避免检查自己的程序,测试工作应该由独立的专业的软件测试机构来完成。软件测试机构来完成。3)3)设计测试用例时,
50、应该考虑到合法的输入和不合法的输入,以设计测试用例时,应该考虑到合法的输入和不合法的输入,以及各种边界条件,特殊情况下要制造极端状态和意外状态,比如网络及各种边界条件,特殊情况下要制造极端状态和意外状态,比如网络异常中断、电源断电等情况。异常中断、电源断电等情况。4)4)注意测试中的错误集中现象,这和程序员的编程水平以及习惯注意测试中的错误集中现象,这和程序员的编程水平以及习惯有很大的关系。有很大的关系。2023-1-245910.3.7 10.3.7 面向对象的面向对象的系统系统测试测试5)5)对测试错误结果一定要有一个确认的过程。一般由对测试错误结果一定要有一个确认的过程。一般由A A测试