面向对象方法学的基本原则
面向对象方法学认为:客观世界是由各种“对象”所组成的,任何事物都是对象,每一个对象都有自己的运动规律和内部状态,每一个对象都属于某个对象“类”,都是该对象类的一个元素。复杂的对象可以是由相对比较简单的各种对象以某种方式组成的。不同对象的相互作用就构成了我们要研究 分析和构造的客观系统。
面向对象方法学认为:通过类比,发现对象间的相似性,即对象间的共同属性,这就是构成对象类的根据。
面向对象方法学认为:对于已分成类的各个对象,可以通过定义一组“方法”来说明该对象的功能,也即是:允许作用于该对象上的各种操作。对象间的相互联系是通过传递“消息”来完成的。
面向对象方法学比较自然地模拟了人类认识客观世界的方法。即应使描述问题的问题空间和解决问题的方法空间在结构上尽可能地一致。我们分析 设计和实现一个系统的方法尽可能接近我们认识一个系统的方法。
面向对象的基本概念
一 对象我们把客观世界的实体称之为问题空间的对象,任何事物都是对象。
我们用计算机解题是借助某种语言规定对计算机实体施加某种动作,以此动作的结果去映射解,我们把计算机实体称之解空间的对象。
在面向对象的程序设计中,“对象”是系统中的基本运行实体。即对象是具有特殊属性(数据)和行为方式(方法)
的实体。
从动态的观点看,对象的操作就是对象的行为。问题空间对象的行为是极其丰富的,而解空间对象的行为是极其死板的。因此,只有借助于极其复杂的算法才能操纵解空间对象而得到解。面向对象语言提供了“对象”概念,这样,程序员就可以定义解空间对象。
从存储的角度来看,“对象”是一片私有存储,其中有数据也有方法。其它对象的方法不能直接操纵该对象的私有数据,只有对象私有的方法才可以操纵它。
从对象的实现来看,“对象”是一台自动机,其中私有数据表示了对象的状态,该状态只能由私有的方法改变它。每当需要改变对象的状态时,只能由其它对象向该对象发送消息,对象响应消息后按照消息模式找出匹配的方法,并执行该方法。
对象的特征模块性:一个对象是一个可以独立存在的实体。从外部看这个模块,只了解这个模快具有哪些功能,模快的内部状态以及如何实现这些功能的细节都是“隐蔽”在模快的内部的。
继承性和类比性:人们是通过对客观世界中的各种对象进行分类及合并等方法来认识世界的,每个具体的对象都是在它所属的某一类对象(类)的层次结构中占据一定的位置。下一层次的对象继承了上一层次对象的某些属性。
另一方面,不同的对象具有某些相同的属性时,也常常把它们归并成一类。
动态连接性:我们把对象和对象间所具有的统一 方便 动态地连接和传递消息的能力与机制称之为动态连接性。
易维护性
二 消息和方法消息对象间的相互联系是通过传递消息来实现的。消息用来请求对象执行某一处理或回答某些信息的要求,消息统一了数据流和控制流,程序的执行是靠在对象间传递消息来完成的。
发送消息的对象称为发送者,接受消息的对象称为接受者。消息中只包含发送者的要求,消息完全由接受者解释,接受者独立决定采用什么方式完成所需的处理。一个对象能接受不同形式不同内容的多个消息,相同形式的消息可以送往不同的对象,不同的对象对于形式相同的消息可以有不同的解释,能够做出不同的反映。对于传来的消息,对象可以返回响应的回答信息,但这种返回并不是必修的。
消息的形式用消息模式刻画,一个消息模式定义了一类消息,它可以对应内容不同的消息。对于同一消息模式的不同消息,同一个对象所做的解释和处理都是相同的,只是处理的结果可能不同。对象固有处理能力按消息分类,一个消息模式定义对象的一种处理能力。所以,只要给出对象的所有消息模式及相应于每一个模式的处理能力,也就定义了一个对象的外部特征。消息模式不仅定义了对象所能受理的消息,而且还定义了对象的固有处理能力。
方法把所有对象分成各种对象类,每个对象类都定义一组所谓的“方法”,它们实际上可视为允许作用于诶对象上的各种操作。
三 类和类层次
在面向对象程序设计中,“对象”是程序的基本单位,相似的对象可以归并到一类中。
类由方法和数据组成,它是关于对象性质的描述,包括外部特性和内部实现两个方面。类通过描述消息模式极其相应的处理能力来定义对象的外部特性,通过描述内部状态的表现形式及固有处理能力的实现来定义对象的内部实现。
一个类实际上定义的是一种对象类型,它描述了属于该类型的所有对象的性质。
对象是在执行过程中由其所属的类动态生成的,一个类可以生成多个不同的对象。同一个类的对象具有相同的性质。
一个对象的内部状态只能由其自身来修改。因此,同一个类的对象虽然在内部状态的表现形式上相同,但可有不同的内部状态。从理论上讲,类是一个抽象数据类型的实现。
一个类的上层可以有超类,下层可以有子类,形成一种类层次结构。这种层次结构的一个重要特点是继承性,一个类继承其超类的全部描述。这种继承具有传递性。所有,一个类实际上继承了层次结构中在其上面的所有类的全部描述。
因此,属于某个类的对象除具有该类所描述的特性外,还具有层次结构中该类上面所有类描述的全部特性。
抽象类是一种不能建立实例的类。抽象类将有关的类组织在一起,提供一个公共的根,其它的子类从这个根派生出来。
抽象类刻画了公共行为的特性并将着些特征传给它的子类。通常一个抽象类只描述与这个类有关的操作接口,或是这些操作的部分实现,完整的实现被留给一个或几个子类。抽象类已为一个特定的选择器集合定义了方法,并且着些方法服从某种语义,所以,抽象类的用途是用来定义一些协议或概念。
综上所述,类是一组对象的抽象,它将该种对象所具有的共同特征集中起来,由该种对象所共享。在系统构成上,则形成了一个具有特定功能的模块和一种代码共享的手段。
四 继承性
继承性是自动的共享类 子类和对象中的方法和数据的机制。
每个对象都是某个类的实例,一个系统中类对象是各自封闭的。如果没有继承机制,则类对象中数据和方法就可能出现大量的重复。
多重继承:如果一个类可以直接继承多个类,则着种继承方式称为多重继承。
简单继承:如果限制一个类至多只有一个超类,着种方式称为简单继承。
继承的四种类型替代继承:如果我们能够对类T的对象比类E的对象实施更多的操作,就说类T继承类E,即在类E的对象处,能够用类T的对象来替代。这种继承是基于方法而非值。
2 包含继承:如果类T的每个对象也是类E的对象,则说类T是类E的子对象。这种继承是基于结构而非操作。
限制继承:如果类E包括满足某种已知限定条件的类T的所有对象,则类T是类E的一个子类特化继承:如果类E的对象是类T的对象,而T带有更多特殊信息,则类T是类E的子类。
继承性是实现从可重用成分构造软件系统的最有效的特征,它不仅支持系统的可重用性,而且还促进系统的可扩充性。
五 封装性
封装是一种信息隐蔽技术,用户只能见到对象封装界面上的信息,对象内部对用户是隐蔽的。封装的目的在于将对象的使用者和对象的设计者分开,使用者不必知道行为实现的细节,只需用设计者提供的消息来访问该对象。
封装的定义为:
一个清晰的边界,所有的对象的内部软件的范围被限定在这个边界内。
一个接口,这个接口描述这个对象和其它对象之间相互的作用。
受保护的内部实现,这个实现给出了由软件对象提供的功能的细节,实现细节不能在定义这个对象的类的外面访问。
面向对象的语言以对象协议或规格说明作为对象的外界面。协议指明该对象所接受的消息,在对象的内部,每个消息响应一个方法,方法实施对数据的运算。对数据方法的描述是协议的实现部分或叫类体。
显式地将对象的定义和对象的实现分开是面向对象系统的一大特色。
六 多态性
当同样的消息可以送到一个父类的对象和子类的兑对象上时,这被称作多态性。
所谓多态即一名字可具有多种语义。在面向对象的语言中,多态引用表示可引用多个类的实例。由于多态具有可表示对象的多个类的能力,因而,它既与动态类型有关又与静态类型有关。
多态性支持“同一接口,多种方法”。
面向对象分析
作为一个比较全面的方法,面向对象分析由五个主要步骤组成,即确定类与对象,识别结构,识别主题,定义属性和定义方法。一旦建立了模型,就可以由五个层次来表示,它们是:
主题层 主题给出分析模型的总体概貌。
对象层 对象是数据及其处理的抽象。它反映了系统保存和处理现实世界中某些事物的信息的能力。
结构层 结构表示问题域的复杂性。类—成员结构反映了一般 — 特殊关系,整体 — 部分结构反映了整体和部分的关系。
属性层 属性就是数据元素,可用来描述对象或分类结构的实例,可在图中给出并在对象的存储中定义。
方法层 方法是在收到消息后必须进行的处理,在图上定义它并在对象的存储中指定。
一 确定类与对象什么是类 对象在面向对象分析中对象是一个封装体和抽象体,即是属性和处理这些属性的方法的封装体以及问题域的抽象体。
类是对一个以上对象的共同属性和方法集合的描述,包括如何在一个类中建立新对象的描述。
属性以及处理这些属性的方法的封装体对面向对象分析模型的稳定性影响很大。首先,封装性是可以将属性和方法看成一个不可分割的整体的基础。第二,封装性有助于减少重复劳动。
在面向对象分析中,对问题域中某件事情的抽象是很重要的。事实上,在每次分析活动中,分析人员必须首先理解要分析的问题域。而将对象定义为现实世界的抽象,这样有助于深刻理解问题域,从而获得系统模型。这种模型至少可以产生一个现实的 可观察且可管理的模型层集合,包括主题 对象 结构 属性和方法。
为什么要识别对象识别对象的主要目的是为了使一个系统的技术表示同现实世界更为接近。这种分析的表示和策略是依据人类的三种基本本分析方法的,即对象和属性,类与成员,以及整体和部分。
识别对象的另一个目的是希望建立考察问题域和了解需求的稳定框架。对象只是相对稳定的,但分析问题的框架却是稳定的。
最后一个动机是希望在从系统分析向系统设计过渡时不要改变所采用的表示法。
如何定义对象。
表示法
类-&-对象 类
何处去确定对象问题域 文字说明 和图形表示都是有助于确定对象的素材。
首先应该观察问题域并研究问题域本身。
其次是研究文字说明材料。
最后是要仔细地观察各种图形表示。
哪些可以作为对象结构。 问题域中的结构对确定对象和表示问题域层十分重要。在面向对象分析中,有专门的一个识别结构的步骤。
有关系统。 所考虑的系统将以何种方式同有关的系统和外部终端交互?
装置。 所考虑的系统需要同何种装置交互。
应记忆的事件。 系统是否有必要观测和记录时间点和历史事件。
所起的作用。 在所考虑的系统中,人起什么作用?
地点。 所考虑的系统需要什么样的地理知识?
组织结构。 人属于哪个机构?
应考虑那些内容
如果已找到一个候选对象,是否要放到模型中去?应考虑以下问题
必要的记忆。是否该系统需要记忆某个对象的所有情况?能否描述该对象的实例?该对象的潜在的属性是什么?是否系统需要记忆与该对象有关的情况?如果这一切的回答都是 否定的,则该对象的存在就值得怀疑了。
必要的方法。系统是否需要该对象提供的方法?
一个以上的属性。
共同属性。能否识别一组每个对象都有的属性?
共同的方法。能否识别一组共同的方法?
对什么提出否定意见并非必要的记忆;
并非必要的方法;
单个实例;
派生结果
为对象命名
对象名应该能描述对象的实例的基本特征。
二 识别结构什么是结构从一般意义上来说,结构是一种思维组织的方式。在面向对象分析中,结构是问题域复杂关系的表示,它与系统的任务直接相关。结构有一般 —— 特殊结构和整体 —— 部分结构。
为什么要定义结构识别结构能使分析人员的注意力集中在多个类和对象的复杂问题上。使用结构能使分析人员考虑到问题的边缘,并揭示那些尚未发现的类和对象。
定义一般 — 特殊结构的策略将每个类看成一般类。针对它的潜在特殊类提出以下问题:
它是属于该问题域吗?
它是该系统的任务吗?
存在继承性吗?
特殊类满足类与对象的准则吗?
再以类似的方式,将每个类考虑为特殊类,并对它的潜在一般类提出同样的问题。
采用继承来显式表达属性和方法的共同部分,可以实现在一般 特殊结构中恰当地分配属性和方法。将共同的属性和方法放在上层,而将特有的属性和方法放在下层。
每个一般 特殊结构均形成层次或网络。
网络能描述复杂的特殊类;能有效地表示公共部分;对模型的复杂程度影响较少。
泛化 — 特化结构表示法 用类作为泛化类
定义整体 部分结构的策略策略由两部分组成,首先,当确定潜在的整体 部分结构时,考虑以下的变种情况:
总成 —— 部件容器 —— 内容集合 —— 成员然后在将每个对象看成整体的前提下,针对它的潜在部分,考虑下列问题:
是否属于该问题域?
是否属于该系统的任务?
所反映的是多个状态值吗?
是否提供了有价值的抽象?
同样,在将每个对象看成部分的前提下,对每个潜在的整体考虑同样的问题。
1,m 1,m户 0,m
1 1 0,1
整体—部分结构表示法 总成—部件关系
三 识别主题什么是主题在面向对象分析中,主题是一种知道读者或用户研究大型复杂模型的机制。
在初步面向对象分析的基础上,主题有助于分解大型项目。
主题所提供的机制可控制一个用户必须同时考虑的模型数目。同时它还可以给出面向对象分析模型的总体概貌。
主题所依据的原理是整体—部分关系的扩充。因此,识别主题的主要基础是以泛化—特化结构和整体—部分结构为标志的问题复杂性。在这种方式下,主题就是用来同整个问题域和系统任务这个“总体”进行通讯的“部分”。
为什么要识别主题人类的短期记忆能力限于一次记忆5—9个对象。这就是著名的7加减2原则。面向对象分析从控制可见性和知道读者的注意力这两个方面来贯彻这一原则。首先通过控制分析人员能见到的层次数目来控制可视性;其次可以对读者进行引导。面向对象分析增加了一个主题层,它可以从一个相当高的层次来表示总体模型。该主题曾能知道读者观察模型,总结问题域的主题。
如何定义主题选择主题为了选择主题,应该:
为每个结构相应地增加一个主题。
为每个对象相应地增加一个主题。
如果主题的数目超过7,则进一步精炼主题。在识别属性和方法的阶段,一旦确定了对象和结构之间的连接关系,就可以将紧密耦合的主题结合起来以便得到更好的主题层。
精炼主题为了精炼主题,可从问题域和接口两方面入手。
使用问题子领域来精炼主题:就是按领域而不是按功能分解的方式来确定主题。
通过使对象间的依赖性最小和交互最少的原则来确定主题:对象间依赖性是由结构和实例连接来表示,而交互则是由消息连接来表示的。
构造主题在主题层上标出主题以及主题间的消息连接。
为主题编号。为了方便通信,每层都要形成一个按主题来分组的图。
将主题画成一个小方框并取一个适当的名字。连接在案主题层上显示,它反映了该主题和其它主题之间的关系。
4)何时引入主题
何时引入主题取决于模型本身的复杂性。对一个很小的系统来说,也许不需要主题层;对有较多的对象的系统,应该首先识别对象和结构,然后再识别主题;对很大的项目需要首先识别主题。
四 定义属性
什么是属性在面向对象分析中,“属性”被定义用来反映问题域和系统的任务。一个属性就是一些数据(状态信息),它在类的每个对象中均有自己的值。
为什么要定义属性主要原因是属性能为“类-&-对象”以及结构提供更多的细节。
属性的值(状态)将由该对象的方法来处理。我们把属性和对这些属性进行操作的方法靠成一个不可分割的整体。
随着时间的推移,问题域的“类”保持稳定,但属性却可能改变。
如何定义属性识别属性首先要明白某个类的对象应该描述什么东西?从单个对象的角度来看,需要询问以下问题:
一般情况下怎样描述该对象?
在本问题域中怎样描述该对象?
在本系统的主要上下文中怎样描述该对象?
紧接着询问以下问题:
该对象需要了解什么?
该对象需要记住什么状态信息?
该对象能处于什么状态?
同时回忆从前对相同和类似问题域实行面向全国对象分析的结果。看哪些属性可以重新使用。在定义属性方面可吸取哪些教训?
在原子概念的层次上标识属性,使每个属性只代表一个“原子概念”,它可以是一个单独的数据单元,也可以是数据单元的一个自然组合。表示“原子概念”的动机是为了产生一个供人观察的简单模型,该模型可能只有几个属性名和自然数据组。
定位属性将每个属性放到它最合适的类-&-对象中。在大多数情况下,这是直接的。
对于泛化—特化结构中的类,如果将某个属性放到结构的最上端的类,则该属性适合它所有的特化类。如果每个属性适合于某层的所有特化类,则应将它向上移动到响应的泛化类。
如果你发现某个属性有时有值,而有时又没有值,则应研究该泛化—特化结构,看是否存在着另外一个泛化—特化结构。
识别实例连接属性可以描述对象状态,而实例连接则加强了这种描述能力。
一个实例连接就是一个问题域映射模型,该模型反映了某个对象对其它对象的需求。
0,m
1
实例连接的表示兑现的每条实例连接上均标有量(m)或者范围(m,n),它反映了该对象对其它对象的约束。该量或范围表明可能发生的映射数目或范围。
策略。
重用以前的结果为每个对象增加连接线到其它对象。
增加对象间的主题映射,并注意泛化—特化结构上的连接。
为没个对象定义从它出发的连接的量或范围,其中,下限:如果可选则为0,如果是强制性的,则为1或更大;上限:如果为单值则为1,如果为多值则比1大。
在上限比1大的情况下,查看是否某些对象有特殊含义,如果如此,则给该对象相应的类--&--对象符号增加一个属性。
如果约束是用在某个对象的多个实例连接上的,则它们可在类--&--对象规范模板的“附加约束”节中加以描述。
4)。检查特例当增加属性和实例连接时,需要考虑以下特殊情况。
(1)属性特例检查具有不合适值的属性。
如果某个属性有时有合适的值,而有时又没有,则应该用泛化—特化结构策略再次查看是否还存在另一个泛化—特化结构。
检查单属性的类-&-对象。
当遇到只有一个属性的类-&-对象时会有如下两种可能:
它是问题域中某事物的一个抽象,本身只有一个属性。这种情况正好。
它是另一个类-&-对象的一个属性,不适合于该模型。
检查每个重复值属性。
确定潜在的重复属性值。如果某个属性有重复值,利用“确定类-&-对象策略”可以找到一个额外的类
(2)实例连接的特例。
检查每个多对多实例连接。
一个多对多实例连接在每个都有大于1的上限。对这样一个连接,什么样的属性能描述它。是否需要定义额外的类-&-对象。
检查同类对象之间的实例连接。
如果某个映射关系意义比较简单,则只要用该实例连接加上它在类-&-对象规范的“附加约束”节中的描述就足够了。否则,应查看一下是否需要增加一个新的类-&-对象,以便得到该映射的更多细节。
检查对象间的多重实例连接。
多重映射隐含着某些语义特征,这些特征可用另一个类-&-对象来描述。
检查所需的附加实例连接。
考虑每对对象,并询问以下问题:
该映射是否在问题域中?是否在系统的任务范围内?
是否该映射在越过其他实例连接时仍然是合适的?如果是合适的,则不需要增加一个实例连接,如果是不合适的,则要增加所需要的连接。
检查有着特殊意义的连接对象。
当某个连接具有特殊含义时,则给受影响的类-&-对象符号增加一个属性。
指定属性为每个属性取可读性好的名字。然后给每个属性加上简短描述。
考虑为每个属性增加约束。如果某个约束能简化或减少工作量,则值得增加。
五 定义方法什么是方法在面向对象分析中,方法是指某个对象所具有的行为。一个方法就是收到一条消息后所执行的处理。
定义方法的中心问题是定义所要求的行为。一般有三种常用的行为分类方法:
有直接动因的行为; (状态—事件—响应)
进化史上的相似行为; (对象生命历程)
功能相似的行为。 (最基本的方法)
为什么要定义方法方法进一步细化了现实的抽象表示,它表明某个类的对象能提供何种行为。
每个数据系统都必须有“数据”和“处理”,方法对应于“处理”。
如何定义方法识别对象状态从创建之时起到释放之时止,每个对象要经历不同的状态。一个对象的状态是由其属性的值来决定和表示的。属性值的每一次改变将反映对象状态的一次变化。
一个对象状态是属性值的标识符,它反映了对象行为的改变。为了识别对象状态,需要检查属性的潜在值,然后再确定这些潜在值的不同行为是否属于系统的任务范围之内。
对象状态图代表一个对象在不同时期的不同的状态或模式,该图能识别状态以及状态转换。
状态
转换 关
等待
监视
传感器的状态图
识别所要求的方法简单算法方法简单算法方法可用于模型中的每一个类-&-对象。它们遵循同一个基本模式。
这四种简单算法方法就是创建(Create),连接(Connect),访问(Access)和释放(Release) 。
创建:该方法建立和初始化该类的一个对象。
连接:该方法将一个对象与另一个对象连接起来。
访问:该方法取出或设置一个对象的属性值。
释放:该方法释放(解除连接和删除)一个对象。
系统所要求的大多数性能均可由以上4种隐含方法提供。
复杂算法方法
复杂算法方法主要分为两类:
计算(Calculate)—— 该方法根据一个对象的属性值计算一个结果。
监视(Monitor)—— 该方法监视一个外部系统或装置。它处理外部系统的输入和输出,负责装置的数据获取和控制。
考察对象的状态并询问以下问题:对象在其值上所实行的是何种计算?对象为了检测和响应外部系统或装置的变化所实行的是何种监视。
识别消息连接
(1)什么是消息连接在面向对象分析中,消息连接是指一个对象到另一个对象的映射(偶尔到一个类)。
其中“发送者”向“接受者”发送一个消息,以使得某些处理功能得以实现。所需的处理是在发送者的方法规范中命名,并在接受者的方法规范中定义的。
消息连接完全是为了方法而存在的。跟踪消息连接有助于确定该对象同系统其它部分的处理相关性,然后才去考虑该对象本身的行为。
(2)为什么要识别消息连接处理复杂问题的一条原则就是用消息通信。
从效果看,消息连接组合了时间响应和数据流两种观点,这就是说每个消息连接代表着一个上下文所发送的值和作为结果而接收到的响应。
消息连接的表示法
发送者 接受者
识别消息连接的策略为了识别所需的消息连接,必须对每个对象询问以下问题:
它需要哪些其它对象提供方法?画一个箭头到这些对象中的每一个;
哪些其它对象需要它的方法?从这些对象中的每一个画一个箭头到所考虑的对象;
沿着消息连接到下一个对象,并重复这些问题。
从一个消息到另一个消息,再到一个消息。这种执行线程有助于分析人员检查模型的完整想和确定实时处理需求。这些执行线程可加上分析约束,特别是对实时系统而言。线程本身是用消息连接和规范正文来描述的。
指定方法可使用方法图来指定方法。
条件
正文块
循环
连接符
方法图以预条件 触发和终止条件来表达与状态有关的行为。
六 类-&-对象模板
specification (对象名)
attribute (由occur操纵的属性)
attribute (可适用于多个对象或分类结构实例的属性)
attribute (只是偶尔可导出的属性)
externalInput (来自设备或外界系统的输入)
externalOutput (向设备或外界系统的输出)
objectStateDiagram (对象状态图)
additionalConstraints (附加约束)
note (分析折衷考虑)
method <name & Method Chart> (方法名和方法框架图)
traceabilityCodes (用来回溯到以前的需求文档的代码)
applicableStateCodes (合适的状态代码)
timeRequirements (时间要求)
memoryRequirements (记忆要求)
七 从面向对象分析到面向对象设计
OOA与OOD的比较从面向对象分析到面向对象设计是一个逐渐扩充模型的过程。面向全国对象分析主要模拟问题域和系统任务,而面向对象设计是面向对象分析的扩充,主要是增加各种组成部分。
具体来说,面向对象分析识别和定义类-&-对象,这些类-&-对象直接反映问题域和系统任务。而面向全国对象设计识别和定义其它附加类-&-对象,它们反映需求的一种实现。面向全国对象分析和面向对象设计是开发系统时的两个不同的阶段。
多层次 多组成部分模型多层次 多组成部分模型由5层组成,在设计期间主要扩充为4个部分。
人机交互部分:有效的人机交互所必需的实际显示和输入。
问题域部分:面向对象分析的结果放在问题域部分。在该部分中,需要管理面向对象分析的某些类-&-对象 结构 属性和方法的组合与分解。
任务管理部分:任务定义 通讯和协调,也包括硬件分配 外部系统以及装置协议。
数据管理部分:对永久性数据的访问和管理。
人机交互部分 问题域部分 任务管理部分 数据管理部分
主题层
类-&-对象层
结构层
属性层
方法层
多层次 多组成部分模型
八 面向对象设计面向对象设计范式面向全国对象的设计范式采用建模的观点。在传统的软件生命周期中,分析和设计同开发问题域的模型紧密相关。而在面向对象的生命周期中,保留了明显的独立结构。人们通过把问题域作为一系列相互作用的实体可以构造出模型。实体的基于软件模型以及模型间的关系汇集成应用程序的基本结构。这样,在分析阶段开发的信息就成为设计阶段的一个主要部分。这种极其自然的过渡是利用了“构件”的一致性。这种一致性与结构化分析和结构化设计有着完全不同的观点。
由面向对象范式产生的勾结是实体描述,即类。许多这样的描述可直接地反映原始问题,尽管许多类并不表示物理对象,但它们是概念上的实体,可以用问题域的术语来瞄准。
在面向全国对象的语言中,世界被看作独立的对象的集合,相互之间通过过程(通常称作消息)进行通信。对象是主动的,而过程(消息)是被动的,过程(消息)和它们的参数一起被从一个对象传递到另一个对象。一个对象根据提交给它的请求(即过程过又称做方法)并基于这些过程(方法)进行行动,因此以数据(即对象)为中心。由于抽象数据类型普遍地被应用于模拟应用领域内的实体,它们为程序的模块化提供了一个自然的基础,其面向对象程序的机构可以非常相似于应用领域中的结构。
实体和实体间的关系面向对象的设计首先涉及到的是实体。实体可以是现实中的对象,也可以是抽象概念。
实体间的关系指发生在问题域中的对象间的相互作用。两个实体之间的关系可能不止一种,一个实体可能与其它的几个实体有关系。
面向对象范式的一种重要设计关系是继承关系。继承关系表示现有定义的特化。
面向对象范式的另一种设计关系是成分关系。成分关系用于在类的实现中提供的一种服务设施。
完整的数据模型面向对象的设计包括类设计和应用设计两个部分,并且被融合在应用开发中。类设计可以隐含在应用设计中,而应用设计包括确定问题域中的各种实体以及实现求解的一些特定实体。每个实体的类型都引出类描述,一旦开发出概念上完整的类描述,就可以设计出应用系统。通过连接类实例(对现实世界建模),利用它们相互间的作用,从而产生问题的解。
类描述包括三部分:属性定义,类接口描述和类实例的可能状态之间的有效变换集。
类实例间相互作用的模式确定了应用系统的结构。这些相互作用是类与类之间的关系模型。
语义数据模型提供了支持开发应用程序的完整的数据模型,这种应用程序包含有高级应用关系和低级类定义关系。
这样,开发一个面向对象应用系统就成为组合类描述和应用系统结构。许多过程都是由现实世的来指导的,而不是用我们求解问题的观点。这就形成在高层包含问题域模型的应用设计。应用设计过程从顶层开始,经过识别类到低层,然后基于低层定义来设计低层类,再进行向上设计。
类的设计准则在任何面向对象的应用中,类实例是系统的主要组成部分,而且如果采用纯面向对象的方法,那么整个系统就是由类实例组成的。因此,每个独立的类的设计对整个应用系统都有影响。我们进行类的设计时要考虑以下因素。
类的公共接口的单独成员应该是类的操作符;
类A的实例不应该直接发送消息给类B的成分;
操作符是公共的当且仅当类实例的用户可用;
属于类的每个操作符要么访问要么修改类的每个数据;
类必须尽可能少地依赖其他类;
两个类之间的相互作用应该是显式的;
采用子类继承超类的公共接口,开发子类成为超类的特化;
继承结构的根类应该是目标概念的抽象模型。
前4条准则着重讲述类接口的适当形式和使用。
准则1要求的信息隐蔽增强了开发表示独立的设计。
准则2进一步说明了这种封装性,它禁止访问用作为类的部分表示的类实例。这些准则都强调了一个类是由其操作集来刻划的,而不是其表达的思想。
准则3把公共接口定义为在类表示中包含了全部的公共操作集。
准则4要求属于类的每个操作符都必须表示其建模的概念行为。
这4条准则为设计者指明了开发,分解类接口以及类表示的方向。
后4条准则着重考虑类之间的关系。
准则5要求设计者尽可能少地连接一个类与其它类。如果一个正被设计的类需要另一个类的许多设施的话,也许这种功能应表示成一个新类。
准则6试图减少或者消除全局信息。一个类所需要的任何信息都应该从另一个类中用参数显式地传递给它。
准则7禁止使用继承性开发新类的公共接口之外的部分。利用类实例作为另一个类的部分表示的最佳方法是,在新设计的类表示中声明支持类实例。
准则8鼓励设计者开发类的继承结构,这种类是抽象的特化。这些抽象导致了更多的可重用子类,并确定了子类之间的不同。