C++程序设计(十)—— 面向对象设计

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/Alexshi5/article/details/82847759

一、过程抽象和数据抽象

        抽象是形成概念的必要手段,它是从许多事物中舍弃个别的、非本质的特征,抽取共同及本质性的特征的过程。

        抽象是面对对象方法中使用最为广泛的原则。类是对象的抽象;数据成员是事物静态特征的抽象;成员函数是事物动态特征的抽象。在软件开发领域,早在面向对象方法出现之前就已经开始运用抽象的原则,主要是过程抽象和数据抽象。

⑴ 过程抽象

        过程抽象是指任何一个完成确定功能的操作序列,使用都可以把它看作一个单一的实体。运用过程抽象,开发者可以把一些复杂的功能分解为一些子功能。

⑵ 数据抽象

        数据抽象是根据施加于数据之上的操作来定义数据类型,并限定数据的值只能由这些操作来修改和观察。20世纪70年代后期形成的抽象数据类型理论明确提出把数据及其操作结合成一个整体并实行信息隐蔽,这是对数据抽象原则的进一步发展。

二、发现对象并建立对象层

        软件开发者将被开发的整个业务范围称作“问题域”,可以按如下步骤考虑发现对象并建立对象层:

1、将问题域和系统责任作为出发点

        问题域侧重客观存在的事物与系统中对象的映射;系统责任侧重于系统责任范围内的每一项职责都应落实到某些对象进行完成。

2、正确运用抽象原则

        要正确运用抽象原则,紧紧围绕系统责任这个目标去进行抽象。抽象就意味着要有所取舍,取舍的准则是看被观察的事物及其特征是否与当前的目标有关。

        在OOA中正确的运用抽象原则,首先要舍弃与系统责任无关的事物,只注意与系统责任有关的事物;其次,对于与系统责任有关的事物,要舍弃那些与系统责任无关的特征。判断事物是否与系统责任有关,一是看该事物是否为系统提供了有用的信息,二是看它是否向系统提供了某些服务。

        要想进行正确的抽象,还需要考虑一些更深入的问题,即应该把问题域中的事物映射为哪种对象,以及如何对这些对象进行分类,而且分类的方法也不是唯一的。

3、寻找候选对象的基本方法

        寻找候选对象要从问题域、系统边界和系统责任三个方面着手。

⑴ 考虑问题域中可以启发分析人员发现对象的因素;

⑵ 考虑系统边界可以启发分析人员发现一些与系统边界以外的活动者进行交互并处理系统对外接口的对象;

⑶ 考虑系统责任可以检查所存在的疏漏,通过对照系统责任所要求的每一项功能,查看是否可以由现有对象完成。

4、审查和筛选对象

        为了尽可能全面的发现系统所需要的对象,分析员应该首先尽可能地找出各种有用的候选对象,然后对发现的候选对象逐个进行严格的审查,筛选掉那些不必要的对象,或者对它们进行适当的调整与合并,使系统中对象和类的数量尽可能的少一些。对对象进行审查和筛选,一般要遵循以下原则:

⑴ 舍弃无用的对象;

⑵ 对象精简;

⑶ 目前不需要考虑的对象。

5、异常情况的检查和调整

        一般如果有以下情况都算异常情况,需要进行调整。

⑴ 类的数据成员和成员函数不适合该类的全部对象;

⑵ 不同类的数据成员或成员函数相同或相似;

⑶ 对同一事物的重复描述。

三、定义数据成员和成员函数

1、寻找数据成员的一般方法

 ① 考虑对象有哪些直观的数据成员;

② 在当前的问题域中,这个对象应该有哪些数据成员;

③ 根据系统责任的要求,这个对象应该有哪些数据成员;

④ 考虑建立这个对象是为了保存和管理哪些信息;

⑤ 考虑对象为了在服务中实现其功能,需要增设哪些数据成员;

⑥ 考虑对象有哪些需要区别的状态,是否需要增设数据成员;

⑦ 考虑用什么数据成员表示整体——部分结构和实例连接,对于整体——部分结构,整体对象应有表明其部分对象的数据成员。

2、审查与筛选数据成员

        审查和筛选可对每个数据成员提出以下问题:

① 这个数据成员是否体现了以系统责任为目标的抽象;

② 这个数据成员是否描述了这个对象本身的特征;

③ 该属性是否符合人们日常的思维习惯;

④ 这个数据成员是不是可以通过继承来得到;

⑤ 是否是可以从其他数据成员直接导出的数据成员。

3、定义成员函数

        使用中要注意区分成员函数、非成员函数和友元函数三者,C++会自动产生一些看不到的默认成员函数,如构造函数、析构函数等。除了从系统责任和问题域方面考虑外,还要分析对象的状态以及追踪服务的执行路线,一般要研究对象的状态和转换图。最后还要检查每个成员函数是否真正有用,它们是否有很强的内聚性。

四、如何发现基类和派生类结构

        定义对象之后,需要研究类之间的关系。

1、学习当前领域的分类学知识

        分析员应该学习一些与当前问题域有关的分类学的知识,因为问题域现行的分类方法往往比较正确的反映了事物的特征、类别以及各种概念的一般性与特殊性(恰好对应C++的基类与派生类概念)。

2、按照常识考虑事物的分类

        如果该问题域没有可供参考的分类方法,可以按照自己的常识,从各种不同的角度考虑事物的分类,从而发现其基类与派生类的关系。需要提醒的是,分类要考虑是否符合分类学常识,基类与派生类结构中的各个类之间的关系应该符合分类学的常识和人类的日常思维方式。

3、构建基类与派生类

        发现基类与派生类的类结构,可以把每个类看作是一个对象的集合,分析这些集合之间的包含关系,如果一个类是另一个类的子集,则它们就应该组织到同一个基类与派生类的结构中去。

4、考察类的成员

        对于系统中的每一个类,一是看一个类的成员是否适合这个类的全部对象;另一方面检查是否有两个或更多的类含有一些共同的数据成员和成员函数。

五、接口继承与实现继承

        公有继承实际上是由两个不同部分组成的,即函数接口的继承和函数实现的继承,概括如下:

① 继承的总是成员函数的接口;

② 声明纯虚函数的目的是使派生类仅仅继承函数接口,而纯虚函数的实现则由派生类去完成;

③ 声明虚函数的目的是使派生类既能继承对此虚函数的实现,又能继承虚函数提供的接口;

④ 声明实函数的目的是使派生类既能继承基类对此实函数的实现,又能继承实函数提供的接口。

⑴ 纯虚函数

        它的两个特征,一是它们必须由继承它们的非抽象类重新说明;二是它们在抽象中没有定义。

⑵ 虚函数

        虚函数一般提供一个可供派生类选择的实现。

⑶ 实函数

        当一个成员函数是实函数时,无论派生类如何变化,它都是不会有所变化的。

猜你喜欢

转载自blog.csdn.net/Alexshi5/article/details/82847759