面向对象仿真

2024-10-16

面向对象仿真(共10篇)

面向对象仿真 篇1

0前言

随着现代互联网的飞速发展,网络规模不断扩大,互联网在给人们带来方便的同时,也给人们带来了诸多的安全威胁,其中蠕虫的威胁尤其严重,它能在短时间内攻破大量主机,导致网络大面积瘫痪,严重影响正常业务的运行,对社会和经济造成重大损失,所以网络蠕虫的研究与防范成为当今网络安全方面研究的重点。

1 蠕虫研究方法

目前人们对蠕虫的研究主要从两个层次进行:微观方面,人们通过对蠕虫个体进行各种动静态分析来剖析蠕虫,以提取对应的特征信息,便于今后对该蠕虫的查杀;宏观方面,人们通过采集蠕虫爆发时给互联网上的相关数据来研究蠕虫的特征,通过对这些宏观数据的分析人们可以了解许多从微观分析方面所无法了解到的蠕虫特征信息,比如蠕虫发作时给互联网所带来的影响等。通过两个层次的分析与综合,人们才能对所研究蠕虫有个较全面的认识,才能制定出较为完整的防范措施。

在微观方面,人们已经有了较多的辅助工具,如用于静态分析的工具有winhex,ultraedit,URSoft w32DASM等,用于动态跟踪分析的工具有ollydbg,SoftICE等,以及其它一些反汇编与反编译软件等。而在宏观方面,由于受基础设施装备与蠕虫爆发的突发性及短期性的影响,实际上很少有单位或研究机构能在准确时间里获取足够的宏观数据来研究蠕虫在宏观方面的特征。同时由于蠕虫的破坏性作用,又不可能允许我们在实际网络中将其不断再现以进行研究,而且现实中也不可能有这么多设备供我们研究使用。

为了解决研究需求与现实危害之间的矛盾,人们想出借助仿真实验来研究蠕虫的方法。本文以NMS(Network Modeling and Simulation)为基础系统介绍了该方法的基本原理。

2 仿真环境的构造

根据计算机网络的定义:“按照网络协议,以共享资源为主要目的,将地理上分散且独立的计算机互相连接起来形成的集合体”,我们可以看出,网络实际上是由一定量主机通过必要的连接设备(如光纤、网关、路由器等)连接在一起所形成的一个网状结构。为了简单起见,我们此处刻画的“网络”更像是图论中的“网络”,按此约定,网络是主机的集合,而主机又是不同软件的集合体(只有安装了软件的主机才能真正为用户提供服务),不同主机间的通信我们用消息来刻画,所以蠕虫仿真环境的构造主要就是对“网络、主机、软件、消息”四种构成因子的建模与仿真。由于每种因子都有其自身的特征与行为,所以用面向对象的方法进行建模与仿真比较恰当,实现起来也比较方便。

2.1 网络

根据实际网络的情况和研究内容的需要,网络主要由以下特征来刻画:

用于刻画主机对象的数组:它包含了组成该网络的所有主机。

消息数:用于描述在该网络中流通的所有消息的数目,用于仿真网络的总体流量信息。

有效消息数:在实际的网络中,并不是蠕虫发出的所有数据包都能有相应的主机与之对应,当目标主机不存在时,相应的数据包会被网络设备自动抛弃,这种包我们认为是无效的。因为要对蠕虫感染主机的情况进行研究,所以有必要对那些有效数据包的数量加以统计,以研究蠕虫发作时对整个网络所可能造成的影响。所以要用一个单独的成员来刻画这个数据,即:有效消息数。

随机数种子:现实网络中每台主机都有惟一的IP地址与之对应(假设每台主机只有一块网卡),在实验中我们可以用互不相同的随机数来代表对应的IP地址,通过选择一个精确的PRNG(Pseado Random Number Generator)就可生成我们所需要的所有主机随机数地址。

最大地址空间:用于控制仿真网络的规模。

构造函数:用于根据用户输入的参数对仿真网络进行初始化,包括网络规模设置、关键成员的清零等。

随机地址生成函数:用它为每台加入网络的主机随机生成互不相同的随机数地址,类似于实际网络中的IP地址自动分配。

主机添加函数:用于向构造函数初始化好的网络框架中添加主机,充实该网络框架。

网络运转驱动函数:该函数通过对主机中相应驱动函数的调用来仿真各主机正处于运转状态之下,从而使整个网络处于运转状态之下。

消息接收函数:用于记录、缓存网络上的通信数据流。

仿真结果输出函数:该函数的作用是将仿真实验所得到的相关数据及时输出。

2.2 主机

主机是人们日常工作的直接操作对象,通过主机人们不仅可以完成本地的操作,还可以通过将主机接入网络与其它的主机进行通信。综合主机的这两个主要应用,一台主机的特征可以用如下的成员变量来加以描述:

主机系统类型标识:是一个用于标识本机所装系统平台类型的字符串,比如:标识“Linux-x86”标识本机所装的是LINUX平台,这样用于攻击WINDOWS系统的蠕虫就对其无影响。

IP地址:用伪随机数生成器生成的随机数来充当,用于定位该主机在网络中的位置。

软件数组:用于存储本机所有安装的软件。

网络标识:用于标识该主机所隶属的网络对象。

接收消息计数:用于描述本机接收到的所有消息的数量信息,为了便于研究又将这些数据分成四类:本机收到的总消息数;与本机系统平台相对应的消息数;被本机软件接收的消息数;对攻击本机真正起作用的消息数。这四类消息数量依次递减。

发送消息计数:用于记录本机所发出的消息数量,由于被感染主机往往会在短时间内向外发送大量的数据包,通过记录本机发送消息的数目可以判断主机是否被感染提供依据。

一台运行着的主机的行为主要是“应用环境搭建、软件运行、网络通信”,所以对于主机的行为可以用以下几个主要的方法进行描述:

构造函数:用于初始化主机对象。

软件添加函数:用于向初始化好的主机对象中加入相应的软件对象。

软件删除函数:从主机上删除某个软件,它与软件添加函数结合全面刻画了软件在主机中的动态变化情况。

随机地址生成函数:实际上它是通过调用对应网络中的随机数地址生成函数来为自己生成随机数地址,这就保证了所有主机地址在整个网络中的惟一性。

消息发送函数:用于描述主机向外发包的过程。

消息接收函数:用于描述主机接收来自外部的数据包的过程,它与消息发送函数结合就描述出了主机间通信的过程。

进程驱动函数:它用于驱动每台主机所安装软件的运行,网络对象类中的运转驱动函数通过对它的调用来模拟整个网络中所有主机运行着不同软件的运转状态。

2.3 软件

软件是一台主机的重要组成部分,借助各种软件,人们来完成各种不同的工作。随着人们对软件需求的增长,软件系统的复杂性越来越高,软件设计由于时间、设计等多方面的原因漏洞无法避免,蠕虫正是利用这些漏洞进行破坏与传播。

根据研究的需要,仿真中软件的特征主要用下面几个成员来刻画:

软件标识:蠕虫往往是借助一个或者几个软件中存在的漏洞来进行传播的,一个蠕虫出现后它所针对的漏洞软件也同时被确定了下来,所以要进行蠕虫仿真,必须要对软件进行标识。

函数代码:由于蠕虫需要在攻下新的主机后将自身的副本传给新感染主机,所以需要在软件的属性中添加一个表示软件的代码的属性。

脆弱性标识:现实中通过打补丁,可以修复系统中软件存在的漏洞,所以并不是所有蠕虫针对的软件都会被攻击,这就要求我们在仿真中添加一个系统中软件是否具有蠕虫所利用的脆弱性的标识。

探测地址:蠕虫为进行传播,都会包含有一定的生成探测地址的机制,用于当一台主机被感染后以此为出发点,不断去探测网络中其它具有相应漏洞的主机。

对于软件的行为,可以用下面几个方法函数加以刻画:

构造函数:构造一个软件对象只要三个参数:软件名称、软件代码、布尔值。

软件运行函数:用于刻划软件在主机系统上的运行。

2.4 消息

消息的主要属性有:

目标地址:消息被发送到的目标主机。

目标系统标识:用于标识可以接收该消息的目标主机的操作系统平台;只有当对方系统的类型与该属性相一致时,该消息才会被目标主机所接收。

目标软件标识:它标识的是该消息所针对的软件,当消息被目标主机接收后,只有目标主机装有该属性所标识的目标软件时,该消息才能起到真正的作用,否则也最终会被抛弃。

函数代码:该属性模拟的是蠕虫个体从一台主机向其它主机传播的过程。

因为在网络中消息充当的角色是信息的载体,没有自主的行为,所以在仿真实验中可以只用一个构造函数来描述它的产生过程。

至此,仿真环境的四个必要因子已经全部构造完成。在仿真实验中,通过以下几个过程就可以构造出一个较为简单的仿真环境:

生成消息对象;

生成软件对象;

生成主机对象,并用前面生成的软件对象将主机对象充实起来,形成一台真正能完成某些功能的个体;

生成网络对象,将前面生成的不同的主机对象加入该仿真网络中,形成一个真正的网络环境;

调用网络对象中的Run( )方法启动整个网络。

3 仿真网络的驱动动力

现实的网络是由不同的主机通过必要的链接设备互联而成的,有实实在在的电力在驱动着它的运转,那么对于一个仿真网络要使其真正运转起来也需要有一定的驱动措施,一种方法可以用循环来作为仿真网络的驱动动力,每一次循环过程作为一个时间单位来看待,循环的不断运行也就相当于仿真网络的不断运转。

因为是实验所以不可能完全像实际网络那样永远运行,为了限制仿真网络运行的时间,我们要用一些条件来约束其运转,这些因素包括:最大循环次数、已感染主机的比率(当所剩脆弱性主机的比率小于一定量时,实验就可终止,因为现实中网络蠕虫爆发时也不可能将所有脆弱性主机全部感染)等。

4 蠕虫仿真的基本过程

在现实网络中,蠕虫传播的基本过程是:蠕虫作者首先通过某些主机将蠕虫释放出来,然后从这些主机出发去搜索其它具有相应脆弱性的主机,发现后通过漏洞去感染新发现的主机,并通过它们间的通信将蠕虫不断向外传播,从而尽可能多地感染主机。仿真环境下蠕虫传播的基本过程也是如此,但不同的是现实中的蠕虫携带攻击代码;而仿真环境下的蠕虫并没有攻击代码,取而代之的是它所利用漏洞的标识,当一个蠕虫副本被传播到一台新的主机上时,若该主机具有相应的漏洞则标识该主机已被感染,否则不会被感染。

下面我们以对Msblast的仿真为例将上面的过程做一简单介绍。

首先,通过步骤(1)为仿真实验设置了各种必要的初始化参数;然后通过(2)生成了一个所需规模的仿真网络;步骤(8)和(9)则分别向前面生成的仿真网络中添加了具有脆弱性的主机和初始被感染的主机;至此,一个MSBLAST蠕虫爆发前的网络环境已经基本构造完成。

实验中,我们通过(10)所指示的循环来作为整个网络运转的动力来源,来模拟现实网络的运行。因为现实网络中蠕虫并不能最终感染所有具有相应脆弱性的主机,也并不是无限期的传播下去,所以我们设置了两个循环终止的条件:一个是网络运转了足够长的时间(用$steps表示),另一个是仿真网络中脆弱性主机的数目已经很小(用$stop_proportion表示)。

随着网络的运转,初始被感染的主机被调动起来,这时它们就会主动去探测其它具有相同脆弱性的主机,当所发出的探测包到达一台新的主机后,首先判断主机的操作系统是否是自己要感染的系统类型,如果是则继续判断主机是否安装有蠕虫所针对的软件,对安装有此次蠕虫所针对的软件的主机,通过判断主机中该软件的exploitable属性就可以知道这是否是一台可被进一步攻击的主机,当新的可感染主机(即:$Host->exploitable=1)被发现后也就进入了MSBLAST仿真代码中(7)所标示的阶段(用$Host::Init表示);随后已感染主机就会通过将蠕虫的副本传送到新被发现的脆弱性主机上去,即上面(6)所表示的阶段(用$Host::Init2表示);随着时间的延续,进入$Host::Init2阶段的新被感染的主机就会作为新的传播机器开始探测和攻击其它主机,即上面(5)所示的阶段(用$Host::Run表示)。随着网络的运转,这样的攻击过程在不断地重复,最终网络中大多数的脆弱性主机被感染。

上述仿真代码最后的部分是对仿真结果的输出。根据我们在P4 3G、256M内存主机上得出的实验数据,我们用GNUPLOT得出MSBLAST蠕虫传播仿真图(如图1),与有关机构根据实际网络采集到的数据得出的实际传播图(如图2)作比较可以看出,我们的仿真思路是正确的,因为它能正确反应出蠕虫传播的整个过程的变化情况。

5 网络蠕虫仿真实验的优缺点

网络蠕虫仿真是重现蠕虫爆发过程的有效工具,与其它的研究方法(比如:数学模型等)相比有其自身的优缺点:

优点:

仿真实验更加直观,好的仿真实验能够采集到高可信度的数据;

通过网络蠕虫的仿真能够及时预测蠕虫发展的趋势从而指导人们及时采取相应的防范措施;

因为整个仿真实验是在个别机器上进行的,而且去掉了蠕虫的攻击行为所以允许我们随意地重复实验,而不会对现实的网络有任何的负面影响;

搭建一个好的仿真环境要比搭建一个真实的网络环境成本要小的多,仿真具有更高的性价比。

缺点:

在仿真过程中为了减小计算复杂性,对所研究对象的内部机制进行了抽象化和近似化处理,因而有可能导致仿真的结果与实际情况有较大差别。优化的方法是对现实中已经观察过的对象进行仿真,通过比较仿真结果与实际情况来改进仿真过程。

由于现实网络的复杂性,仿真实验不可能对网络的各个方面都能很好地涉及,这种不完善性或多或少地造成仿真结果与现实数据的差别。

6 总结

本文通过对仿真网络组成因子的剖析及一个简单蠕虫仿真环境的实际搭建的介绍,叙述了网络蠕虫仿真的基本思路,并通过对Msblast蠕虫的仿真验证了该思路的正确性。相信只要在此思路基础上不断细化仿真的各种环节就可以构造出一个能实现更多仿真功能的仿真平台。

参考文献

[1]Zhang Yu,Zhang Hongli,FANG Binxing.A Survey on Internet-Topology Modeling[J].Journal of Software.2004.

[2]文伟平,卿斯汉,蒋建春,王业君.网络蠕虫研究与进展[J].软件学报.2004.

[3]郑辉.Internet蠕虫研究[D].南开大学信息技术科学学院.2003.

[4]王跃武,荆继武,向继,刘琦.基于拓扑结构的蠕虫防御策略仿真分析[J].计算机学报.2007.

[5]许长伟,向继,鲍春杰,荆继武.蠕虫软件仿真技术研究与进展[J].计算机仿真.2006.

[6]周涛,戴冠中,慕德俊.Internet蠕虫防范技术研究与进展[J].计算机应用研究.2006.

面向对象仿真 篇2

1.类本身就是一个封装单元

2.实现:A属于私有化;B共有的方法提供给外界访问;C信息隐藏,安全,对外提供清晰的接口

二、继承

1.代码共有,方便维护扩展 2.更符合人类遇到的问题及处理的习惯 3.多重继承关系下构造函数的执行过程

三、多态

1.概念

2.好处

3.应用(生活,程序中的应用)

程序多态的应用

1.方法重载

2.重写父类的方法

3.重写父类的抽象方法

4.父类类型作为方法参数,实现

5.以父类的引用,接收不同子类返回的结果

6.用接口实现

四、面向接口编程

1.理解接口

1.1接口体现的是一种能力

体现在接口中的方法

1.2接口的体现是一种约定体现在注释和接口的名称 1.3面向接口编程程序设计时:

A关注实现类有那些功能,不需要关注实现细节

B面向接口的约定不考虑接口

具体的实现2.使用接口如何使用接口?A编写接口<-----根据需求设计接口的方法 B实现接口<-----实现接口里定义的所有方法 C使用接口<-----多态 3.特征1.多实现,弥补单一继承不足 2.项目初期,搭建系统时不需要考虑具体的实现自然使用接口:设计和显现分离 3.方便搭建整个应用系统,及系统设计

也方便搭建系统框架 4.多态应用的很好体现更自然的使用多态

重点:

1.掌握抽象类与接口不同之处 难点:

1.方法重载与重写 2.继承关系下,构造函数执行流程 知识体系:

面向对象数据库系统设计 篇3

关键词:面向对象;数据库;系统设计

一、数据查询(OQL)

作为数据库,最重要的估计是数据查询了,面向对象数据同样如此。在这里,我设计了以下查询语法:get(…)if(…),其中get里面是要查询的类,类的属性等,相当于SQL里面的select … where …。比如有类A,A中有一个属性a(数字型,关于类型后面会说)。则获取所有A类实例中所有a的值小于0的实例集合的查询语句是:get(A)if(A.a<0);

执行该语句应该要返回所有类A实例中所有a小于0的实例集合。具体使用方法如下:

(一)单类查询

即在一个类中进行查询。如:get(A)if(A.a<0);就返回是所有类A实例中所有a小于0的实例集合。而不带条件的查询是get(A);这将返回类A的所有实例。

(二)多类查询

如:get(A,B);将返回类A和类B的所有实例的数据。

(三)方法查询(暂不实现)

(四)表达式计算

如:get(3+3);返回的将是6。

(五)复杂查询

如:get(A.a+B.b,C,C.a/A.a)if(A.a5);这个查询语句将返回的是类A的a字段和类B的b字段的相加之和,类C的实例以及C类字段a与A类字段a的商,并且尽在类A的a字段小于类B的b字段并且(##是并号)类C的字段a的值小于5。此类操作可能比较耗时,并且可能返回重复的数据。如在A类实例和B类实例确定的情况下C类实例变化时将返回多个相同结果的A.a+B.b的值。记住返回的都是集合。

二、数据操作(OML)

(1)插入数据:new 类名(构造函数参数列表);这样即生成了一个实例(即插入一个实例)。举例如下:

Test t = new Test(1,2,3);//假如类Test的构造参数是三个数字类型的参数。

(2)更新数据:直接调用该类实例的引用的属性复制即可实现更新。举例如下:

t.a = 3;//假如类Test有个公有成员a且是数字型的。

可以有更复杂的、有逻辑的更新,如:if(Test.a>3){Test.a = 1;//将所有符合条件的Test类的实例的a字段复制为1,是集合操作。}

又如:while(t.a>0){Test.a——;//只要实例t的字段a的值还大于0,则所有Test的实例的值继续减一。}

(3)删除数据:free(类名)if(删除条件表达式)。如果没有if,则删除此类的所有实例。free(Test)if(Test.a>0);这将删除类Test的实例t。

(4)数据定义(ODL)

定义语言包括类的定义和对象的定义。语法模仿的Java的语法。具体如下:

定义类:

class :定义类,语法如下:class 类名{

属性定义:其中包括变量权限声明,值定义,类型声明,目前仅支持三种类型,字符串型,数字型和 比特型。

方法定义:方法定义,跟Java类似,但目前仅留接口,不做实现。}

下面是一个实例:

class Test{private num a;//数字型;public str b;//字符串型;protected byte c;//比特型,变长比特型,用来存储大容量数据;public void testMethod(num a){//方法定义,目前暂不实现a++;this.a = a;}“;//”一定要加 “;”号,否则不能结束。

alter:更新类。语法如下:alter 类名.字段名或者方法名 =

{//字段或者方法的新式描述,如果没有任何信息,则表示删除该字段或者方法};举例如下:

alter Test.a {public num a;//如果不是命名为a,而是b,则将删除a字段,新建b字段。

该语句将把字段a的访问权限从私有变为公有。下面是更新方法:alter Test. testMethod {public void testMethod(num a){//方法更新,目前暂不实现a++;this.a = a——};

drop:删除类。此关键字只有一个语法,即:

drop 类名;如:

drop Test;//即表示删除Test类。

(5)数据控制使用try{//行为}catch(){}的语法形式,用来控制事务。在try块中的行为必须全部执行成功数据库才会更改,相当于事务提交。如果发生异常(即不能全部执行成功),则事务回滚。同时还要执行catch块中的信息。一般说来,catch块中留空则只回滚事务。

参考文献:

[1]邢斌、高荣芳、刘予东,《基于JSP的学生就业管理系统》,福建电脑。2006-9

作者简介:

面向对象仿真 篇4

由于交通问题的多样性以及交通工程新技术、新概念的不断出现, 交通仿真实验也需要采用新技术、新方法来扩充和完善系统的功能。在国内、外已经被交通仿真系统开发人员普遍采用的面向对象的软件设计思想和方法也越来越凸现出重要性。本文在简单阐述城市交通仿真模型的基础上, 着重介绍采用面向对象的开发技术, 对城市交通系统的构成和运作规律进行对象分析、对象建模和动态建模的过程。

1 基于面向对象的交通仿真模型

1.1 基于面向对象的交通仿真

面向对象方法是20世纪90年代软件开发的主流, 该方法将现实世界中的事物直接映射到软件系统的解空间, 实现了对现实世界的直接模拟[1]。面向对象方法可以增强仿真模型的直观性、可理解性、可扩充性和可重用性。在以面象对象技术开发的系统中, 系统的基本构成是类的实例对象。这些对象对应着问题域中的各个事物, 它的内部属性和方法描述了事物内部的状态和运动规律。交通仿真是建立在随机过程和数理统计基础之上的, 并且在交通工程领域里, 研究对象的确立影响因素较多, 也存在着随机性;虽然国外仿真软件的开发比较成熟, 但它们基本上是采用面象过程的语言进行开发[2], 面对不同的情况进行仿真缺少灵活性。而基于面向对象的交通仿真可动态地、逼真地仿真交通流变量和交通事故等各种交通规律和现象, 深入分析人-车-路三者之间的交通特征, 从而有效地对交通系统进行规划、组织和优化。

1.2 城市交通微观仿真模型

城市交通微观仿真模型通常归结为道路设施模型、交通控制模型、交通生成模型、车辆行驶模型、人机交互模型等五种类型。各类型模型的主要描述功能如下。

·道路设施模型:描述道路几何条件及道路网拓扑关系。

·交通控制模型:描述各类交通控制与管理方案。

·交通生成模型:描述车辆的到达时刻的输入。

·车辆行驶模型:描述车辆行驶当中换道或者超车行为。

·人机交互模型:描述仿真运行的界面和系统的输出界面。

采用面向对象技术进行实体分析是进行对象分析的基本手段, 这里把仿真系统中将要描述的实体分为静态实体和动态实体两类。例如道路和交通规划等在一次仿真运行开始后, 参数不再发生变化, 就可视为静态实体;汽车和控制信号等在系统中要受到其他因素的影响和制约, 随时可能发生变化, 可以视为动态实体。本系统中主要的对象类有:路段类、节点类 (以起点和终点标志的某行驶区域) 、交叉口类、信号灯类、机动车类、非机动车类、行人类、交通标线类、交通标志类、车道类、公交车站类等十一个大类。

2 交通仿真系统的面向对象建模

2.1 对象建模技术 (OMT, Object Model Tech.) 简述

对象建模技术也即三视点技术, 它把分析时收集的信息构造在对象模型、动态模型和功能模型中, 用这三种模型 (见图1) 来描述一个目标系统。其中对象模型是三个模型中最关键的一个模型, 用以描述系统中对象之间的静态关系, 包括构成系统的类和对象, 它们的属性和操作以及之间的联系。动态模型描述的是系统中对象的变化和对象之间相互关系的变迁, 它着重于系统的控制逻辑。功能模型则侧重于系统内部数据的传送和处理。这三种模型, 功能模型定义“做什么”, 动态模型定义“何时做”, 对象模型定义“对谁做”。

下面主要介绍采用面向对象技术建模的关键问题—对象建模和动态建模。

2.2 交通仿真系统的对象模型

对象模型描述的是对象类之间的静态关系, 具体描述如图2所示。

2.3 交通仿真系统的动态模型

动态模型描述的是系统中对象的变化和对象之间相互关系的变迁。通过该模型的建立, 可以确立仿真系统中各个对象的实时状态和控制逻辑。

车辆是整个仿真系统中的核心对象, 车辆行驶模型则是整个仿真系统中最重要的动态模型。由于仿真的整个过程都离不开车辆对象的行进状态, 下面将车辆对象的行进状态分解为驶入道路、持续行驶、驶离道路三个阶段, 分别进行建模。

2.3.1 车辆驶入道路的动态模型

车辆进入道路的动态模型如图3所示, 首先确定将进入道路的车辆的进入时刻、类型、以及车头时距等相关属性, 同时根据路网结构计算最佳行驶路线, 并确定相应的行驶区域和要进入的车道。

2.3.2 车辆持续行驶的动态模型

车辆在道路中持续行驶的过程较为复杂, 影响的外界因素很多。这里认为车辆的运动行为在以跟驰方式进入后[3], 包括了加速、减速、减速停车、启动加速、左转车从直行车间穿插进入五种, 行驶过程当中驾驶员要随时根据信号灯的指示、前方道路情况 (有无车辆、有无公交车停靠、有无行人过街) 、相邻车道情况 (繁忙还是空闲) 来调整车辆的行驶状态 (加速、减速、停车、超车或者换道) , 如图4所示。

2.3.3 车辆驶离道路的动态模型

图5描述的是车辆驶离道路的动态模型。通过检索当前时刻到达目的节点的车辆, 判断该车辆的设定目的地是否与当前位置一致, 如果一致, 则车辆驶离道路。

3 交通仿真系统的对象设计

根据前面完成的对象建模工作, 下面给出主要的对象类的属性和操作 (方法) 。

4 结语

本文采用面向对象中的O M T技术对城市道路交通系统进行了实体分析, 建立了较为关键的对象模型和动态模型, 并进行了具体的对象设计。微观仿真模型对于从操作层面上评估动态交通管理系统是非常必要的[4]。可以预见, 基于面向对象技术的仿真系统的深入研究, 将为进一步改进和完善交通仿真系统奠定良好的基础。

参考文献

[1]任福田、刘小明, 荣建.交通工程学[M].北京:人民交通出版社, 2002.

[2]钟邦秀、杨晓光.面向对象微观交通仿真系统的研究与实现[J].系统仿真学报, 2002 (4) .

[3]郝记秀、郑兆瑞.基于面向对象的交通仿真研究[J].太原理工大学学报, 2004, (7) .

perl面向对象实例 篇5

首先让我们来看看有关 Perl 面向对象编程的三个基本定义:

1.一个“对象”是指一个“有办法知道它是属于哪个类”的简单引用,(对象就是引用变量)

2.一个“类”是指一个“有办法给属于它的对象提供一些方法”的简单的包。(类就是包)

3.一个“方法”是指一个“接受一个对象或者类名称作为第一个参数”的简单的子程序。(类的方法就是第一个参数为类名或对象的方法)

一个类只是一个简单的包

和 C++ 不同,Perl 并不为类定义提供任何特殊语法。实际上类只是一个包而已。你可以把一个包当作一个类用,并且把包里的函数当作类的方法来用。不过,有一个特殊的数组,叫做 @ISA,它说明了“当 Perl 在当前包中找不到想要的方法时,应当继续从哪儿去找”。这就是 Perl 实现“继承”的关键。@ISA中的每个元素都是一个别的包的名字。当类找不到方法时,它会从 @ISA 数组中依次寻找(深度优先)。类通过访问 @ISA 来知道哪些类是它的基类。

所有的类都有一个隐含的基类(祖先类):“UNIVERSAL”。“UNIVERSAL” 类为它的子类提供几个通用的类方法。它提供以下几个方法:isa,can。其中isa用来判断变量是否从某个类继承而来,can后面的参数则是一个方法,判断这个方法是否在这个类或者基类中被定义。另外你可以给UNIVERSAL添加新的方法。一旦给它添加了新的方法,所有的class都可以调用。

给UNIBERSAL添加新方法的例子:

代码如下:

sub UNIVERSAL::log()

{

my($self,$msg)=@_;

print “$self: $msg ”;

}

这样就可以在每个类中调用这个函数,并且log之前会把类名打印出来。

对象仅仅只是引用

Perl中的构造器只是一个子程序,该子程序返回一个被bless处理的引用,这个经过 bless 处理的引用就是人们所说的“对象”,而 bless 的作用就是用来说明这个对象是隶属于哪个“类”。

最简单的构造器:

代码如下:

package Critter;

sub new { bless {} }

如果你希望用户不仅能够用 “CLASS->new()” 这种形式来调用你的构造函数,还能够以 “$obj->new()” 这样的形式来调用的话,那么就这么做:

代码如下:

sub new {

my $this = shift;

my $class = ref($this) || $this;

my $self = {};

bless $self, $class;

$self->initialize();

return $self;

}

一个方法就是一个简单的子程序

方法把它被调用时的对象或者类名称当作它的第一个参数。有两种不同的调用方法的途径,分别成为“调用类方法”和“调用实例方法”。类方法把类名当作第一个参数。它提供针对类的功能,而不是针对某个具体的对象的功能。构造器通常是一个类方法。大多数类方法简单地忽略第一个参数,因为方法知道自己处在什么类里面,也不关心它是通过什么类来调用的。

Perl 提供了两种不同的形式去调用一个方法。最简单的形式是采用箭头符号:

代码如下:

my $fred = Critter->find(“Fred”);

$fred->display(“Height”, “Weight”);

你可以早就熟悉了引用的 “->” 操作符。事实上,因为上面的 $fred是一个指向了对象的引用,因此你也可以把箭头操作符理解为另外一种形式的解引用,

出现在箭头左边的引用或者类名,将作为第一个参数传递给箭头右边的方法。所以上面的代码就分别相当于这样:

代码如下:

my $fred = Critter::find(“Critter”, “Fred”);

Critter::display($fred, “Height”, “Weight”);

简单示例

1、说明

本程序演示了在Perl中如何进行面向对象编程:演示程序包含两个文件:person.pl 和 person.pm,把 person.pl 和 person.pm 放在当前目录下,运行“perl person.pl”即可以看到结果。person.pm定义了名为person的类。person.pl中创建了person类的实例,并测试了person的成员方法。

2、person.pm的内容

代码如下:

#!/usr/bin/perl -w

package person;

use strict;

sub new {

my $class = shift();

print(“CLASS = $class ”);

my $self = {};

$self->{“name”} = shift();

$self->{“sex”} = shift();

bless $self, $class;

return $self;

}

sub getName {

my ($self) = @_;

return $self->{“name”};

}

sub setName {

my ($self, $name) = @_;

$self->{“name”} = $name;

}

sub getSex {

my ($self) = @_;

return $self->{“sex”};

}

sub setSex {

my ($self, $sex) = @_;

$self->{“sex”} = $sex;

}

3、person.pl的内容

代码如下:

#!/usr/bin/perl -w

use strict;

use person;

sub main()

{

my $tom = person->new(“Tom”, “male”);

my $kiss = person->new(“Kiss”, “female”);

my @persons = ($tom, $kiss);

for my $p (@persons) {

printf(“NAME: %s SEX: %s ”, $p->getName(), $p->getSex());

}

}

&main();

4、程序运行结果

代码如下:

CLASS = person

CLASS = person

NAME: Tom SEX: male

再谈面向对象和面向过程技术 篇6

面向对象和面向过程的程序设计技术现在再来谈论,似乎是一个过时的话题。但是,教学中至今针对两者的关系理解不够透彻的学生不在少数。在Java、C++等面向对象的程序设计语言的很多教材里,面向过程的自顶向下逐步求精结构化的程序设计的三种控制结构占据了一定的章节数,其中很多例题是对三种控制结构使用方法的巩固,学生也常常是模仿着这种例题来练习,这常常造成学习面向对象的编程语言,而设计出面向过程的软件的局面,掌握不好面向对象的程序设计方法。20世纪80年代提出的面向对象的程序设计方法之后,对于程序设计的面向对象和面向过程两种方法,大部分教材偏重于讨论它们的区别,产生两种方法是对立的,互无关联的想法大有人在,似乎有了面向对象的技术,就可以不用面向过程。实际上,面向对象的技术是在面向过程的基础上,为程序设计提供了更多的手段和方法,两种技术不是非此既彼的对立关系,不能说面向对象的技术替代了面向过程,如果用面向对象的技术就要把一个软件任务划分成两个层次,第一个层次是做什么,第二层次是怎么做,那么面向对象技术是解决第一个层次的问题,面向过程则是解决第二个层次的问题,只有在两个层次上的任务都完成之后,才能说完成了整个程序设计任务。也就是说这两种程序设计方法只是从不同的层次来完成程序设计的任务,面向对象的技术是在面向过程的自顶向下逐步求精最终将软件分解成为具有三种控制结构的若干方法过程或函数基础之上,又提供了抽象、封装、继承、多态技术手段,从而能够设计出更好更复杂的软件。可以说面向对象技术中存在着面向过程,或者说面向对象技术就是抽象、封装、继承、多态加上顺序、条件、循环三种控制结构的使用。

2 两种技术的包含性

面向对象可以认为又提供“四”种技术:抽象、封装、继承、多态,面向过程有“三”种控制结构:顺序、条件、循环。以Java语言为例,用求1到n的简单问题来分析两种设计方法:

2.1 面向对象的技术是“四”加“三”的技术

(1)建立对象模型(类)———应用“四”的技术

(2)方法的具体实现———应用“三”的技术

2.2 面向过程的技术———仅仅应用“三”的技术

(1)分析出若干函数或过程并给出具体实现的细节

从上述简单的问题可以看出在用面向对象技术设计类后,一个类中就会有若干方法,每个方法完成一个特定的功能,在考虑类的行为功能实现时,显然是面向过程的思维方式,只是这些方法不再独立,而是与数据一起形成了一个有机的整体。面向过程技术存在于经过面向对象方法分析之后的形成的若干类的行为设计中也就是类方法实现之中。

面向对象的设计包含了面向过程,面向对象比面向过程站到了一个更高的层次上,主要进行总体结构模型设计(构建类),对数据和方法进行封装,面向过程主要是写函数或过程也就是确定类中的方法的实现,这也是类中的方法必须要做的步骤;就象我们建一个居民小区,先把围墙建好,决定好里面要做什么,然后还是要在里面进行盖房子的过程一样,要建好居民小区两个步骤缺一不可。所以说用面向对象的技术设计软件时包含了面向过程。

2.3 两种技术的同一性

对于一个方法要讨论的问题的关键问题是数据从哪里来,运算操作之后到哪里去的问题。方法也就是对输入数据进行处理从而得到结果输出,可以说是由三个部分:输入、操作、输出完成的,输入数据可以体现为的两种形式:无参数和有参数;输出数据同样体现为两种形式:无返回值和有返回值;简单的方法可以是无参数和无返回值的,例如:

讨论一下面向对象技术设计的类中的方法的输入和输出的情况。众所周知,无论是面向对象还是面向过程在描述问题时总是围绕着两个方面:方法和数据,教材中常提到面向对象是方法和数据合并或封装,面向过程是方法和数据分开或隔离,这个特性对类中的方法设计有什么影响?直接地具体地在程序设计时能带来什么好处?事实上,由于面向对象实现了数据和方法的封装,它的好处就是使得类中方法的输入数据多了一个来源,也就是输入数据有了两个来源,一个是类中的属性变量,另一个是方法的形式参数,例如上例中的getSum()方法,它是无参数的,那么它运算的数据来源于何处?实际上就是使用了本类中的数据----属性变量,也就是说当类中的属性能够满足类中的方法输入数据的需要,就可以无参数,虽然无参数,但具备有参数的功能,原因是类中的属性是可以随时变化的,这归功于面向对象的封装技术。当然,也可使用方法本身的数据----形式参数,设计出getSum(int n)方法,这就形成了同一方法的两种不同的实现,面向对象技术中的多态性,使这两种方法能够共存于一个类中,增加了类的可适应性和简洁性。如果用面向过程的技术只能设计出一个独立的过程或函数:getSum(int n),因为面向过程的程序和数据是分开的,每个过程也都是独立的,所以过程或函数在设计时没有别的数据来源,只有依赖于自身的形式参数,无法从别处获取数据,只能在方法内部构建形式参数做为伪数据以求得将来真实的数据———实际参数的传递。同理,类中方法处理的数据结果也变成了有两个去处:一个是类中的属性变量,一个是方法的返回值。这就是数据和方法封装在一起的好处,它使得输入输出有了更多的选择,这也是设计方法时解决算法之后要解决的重要问题。

再看下例:

面向对象的继承技术,使得类中面向过程的方法有了更多的功能。就单纯的面向过程的设计方法,没有实现封装、多态,继承等技术做支撑,也就是说缺乏一个可靠的围墙来做保护,使之不能在围墙之内随着问题的变化而变化,所以软件的可维护性、重用性,复杂度具有劣势。而面向对象的技术中也包含了面向过程的设计,面向对象的封装、多态和继承技术又允许同一个类中的面向过程的同一方法设计有更多的实现方式和更多的功能的扩充,如:getSum(),getSum(int n);getMul(),getMul(int n)。面向对象类中的方法的实现可以等同于在封装、多态、继承技术下的结构化程序设计中的函数设计,它使得类中的面向过程的方法设计有更多的实现,具有同一性。只是这些函数都有自己的归属———某一个类。

3 总结

应该看到,很多面向对象语言的教材中的例子严格说来都是用面向对象的语言写出的面向过程的程序,再加上学习程序设计言时大多是以先模仿例题为主,它带来的负面影响就是更加分不清楚两种技术的关系。另外,为什么教材中的例子是用面对象的语言写出的面向过程和程序呢?原因是大部分例题是属于简单的程序,实际上,对于简单和程序也是没有必要一定用对象的方式来思考问题,面向过程反而适用。用对象来理解和分析问题,并设计和开发出由对象构成的软件系统,是面向对象技术的核心,如果用这种方法设计软件它是离不开面向过程的,它是在面向过程的结构化程序设计所运用的三种控制结构之上又增加了类、封装、继承、多态等技术可以说是“四”加“三”技术来构造、测试、重构软件,因此,就有了比面向过程更多的软件设计和实现手段。这些技术能实现复杂系统的设计与开发,可大大提高软件的规范化程度和开发效率,提高软件的可重用性和降低系统的复杂度,这已是不争的事实。关键的问题在于两种思维模式的建立以及对它们包容性、同一性的认识,从而不致于两种方法混淆不清,得到非此既彼的结论,并能根据实际需要正确地选择设计方法。

摘要:面向对象和面向过程的程序设计技术现在再来谈论,似乎是一个过时的话题。但是,教学中至今对两者的关系理解不够透彻的学生不在少数。面向对象和面向过程可以看成“四”和“三”。有了面向对象的技术之后,产生两种技术非此既彼的对立关系的思想是由于过度强调它们的区别造成的。两种思维模式的建立是关键的问题,程序设计中能根据实际需要正确地选择设计方法。

关键词:程序设计,面向对象,面向过程,同一,对立

参考文献

[1]陈志泊.面向对象的程序设计语言C++[M].北京:人民邮电出版社,2009.

从面向过程到面向对象的变革 篇7

1“软件危机”与面向过程方法

20世纪60年代中期,随着计算机技术的逐步成熟,计算机应用范围的逐渐扩大,软件开发领域急剧膨胀,这时,软件开发人员开始面临一个十分严峻的问题——“软件危机”。

“软件危机”主要表现为三点:第一,开发出来的软件的功能和用户的需求往往“牛头不对马嘴”;第二,软件系统的规模和复杂度的扩大让开发人员力不从心,开发过程中的一些错误已经达到开发人员无法掌控的地步;第三,开发出的软件可维护性很差,要复用已有成果或者对其进行扩展都很困难,软件的进化也很难跟上硬件发展的速度。

追究“软件危机”产生的原因,固然有一部分是因为开发者缺乏对大规模软件的管理经验,缺乏正确的方法学指导或者是开发工具的支持(杨健,张晓玲,周少,2006,135-136),但是最关键的问题在于——当时大多数软件开发工作的全过程,包括分析,设计以及编程实现等,都采用面向过程方法。具体来说,在分析阶段,开发人员根据面临的情况,如用户的需求,软件要求的功能等,做出一个物理模型,其次转换成逻辑模型,再通过数据流分析,把这个模型转化数据流图,记录数据字典。在设计阶段,开发人员根据数据流图划分数据类型,并映射到不同的程序模块类型,通过这样完成分析模型到设计模型的转变,并设计出数据结构图。然后,开发人员在此基础上详细的设计每个程序模块内部的结构和算法。常常是把大模块又分成很多小模块,多次分解,最后再设计完成每个小模块的内容。在实现阶段,利用面向过程的编程语言(如C语言等)进行编程,具体实现整个软件系统。

之所以说这一套方法是导致“软件危机”的关键,是因为它不论是在分析和设计上,还是在编程实现上都存在很大的弊端。

第一,面向过程方法的分析手段是不够妥当的。整个分析和设计阶段可以概括为“需求-数据流-程序模块”的模式,所以对于需要解决的问题,在分析阶段并不能直观的显示出各种事物及其关系,而是映射到数据流中进行分析。因此,当系统比较复杂的时候,很难判断基于数据的分析是否有偏差,是否相对于原本的实际问题有出入,或是否存在理解上的错误。也正是因为所有的分析工作是基于数据流的,开发人员在分析阶段就面临和用户沟通上的困难,他们很难和用户解释数据流图中的内容代表了什么,很难通过沟通发现分析结果和用户需求的差距在哪。并且,如果用户在开发工作的中途想改变一些需求或是外界条件发生了变化,开发人员也不能直接改动分析结果,必须重新映射到数据上再做调整。

第二,从分析阶段到设计阶段的转化是有很大的隐患的。所谓的“数据—程序模块”的转型就是依照一些对应原则,把数据流图转化成程序模块,这两种不同的体系之间的转换是否正确,是否合理是没有保障的。这种“需求-数据流-程序模块”的模式就像多人传话一样,第一个人传话给第二个人,第二个人根据自己的理解把话传给第三个人,第三个人再加上自己的理解,得到的结果和原话已经不是一个意思。原本的内容经每个步骤都被不同的体系“转义”了一遍,这样很可能导致设计出的结果和软件需求的本来面貌相差甚远。

第三,由于面向过程的程序语言本身存在很多不足,导致软件开发的实现阶段出现了很多问题。首先,程序的安全性缺乏保障。很多关键的数据既可以被作用于它们的操作访问,也可以被其他的操作访问。并且,面向过程的程序操作都属于“白盒操作”,所有细节都被暴露在外。一个疏忽的数据修改或者程序调用都可能导致整个系统崩溃。其次,程序员的工作非常繁杂。由于数据和函数是分开来处理的,程序员在编程的时候要考虑的因素就很多,每次编写一个函数都必须把详细的注释添加到数据字典中,对于不同类的数据进行一种操作或者同一类数据进行不同操作都必须写不同的代码。这种编程对程序员的水平要求非常高,仅仅让数据和函数一直保持兼容就已经是程序员沉重的负担。在团体合作中,一个程序员要接手另一个程序员的工作往往需要阅读数十页的数据字典,不同的程序员编写的程序可能还存在着名称重复,风格迥异等冲突,这些问题在复杂的系统中将凭空地加大程序员的工作量。再次,软件的可维护性很差。由于数据和函数代码的分离,每当数据发生改动,所有相关的函数都要重写,想对整个程序进行扩充,升级,或者移植到别的背景下重用都面临着大量的代码修改。

2 面向对象方法

我们可以看到,面向过程方法确实给软件开发工作带来了很多困扰,而面向对象方法正是在这种情况下诞生的。面向对象总的来说有三大特点的:封装性,继承性和多态性。

封装性是面向对象最基本的特点,因为它体现了面向对象最基本的思想:客观世界是由各种对象组成的,复杂的对象可以由比较简单的对象以某种方式组合而成(符于江,2008,451-456)。所有的对象都具有静态属性和动态行为,把相似对象的属性和行为抽象出来,用这些共同的属性(数据)和行为(方法)构成类,作为创建具体对象的模板。封装性就是指把关于一个类的所有数据和方法一起封装在类的内部,只通过一些方法作为对外沟通的接口,外界只能通过这些接口和对象进行联系,而对象内部的很多数据和具体操作是对外不可见的。

继承性是指对于一些具有一般意义的类,可以创建它们的子类,子类可以继承一般类的所有属性和方法,同时可以根据自己的特性,修改继承得来的属性和方法或者添加自己独有的属性和方法。比如对于一般类“亚洲人”,我们可以创建子类“中国人”,“韩国人”等。

多态性有两种形式。第一种是一个类中同名字的方法可以接受不同类型的参数,对于不同类型的参数的处理是不同的。比如在一个类中定义“add”方法实现数的相加,它既可以处理整形的参数,也可以处理浮点型的参数,还可以处理一些自定义类的参数,但是针对每个类型都有各自的处理操作。第二种多态和继承性有关。由于某个父类可以有多个子类,每个子类都可以根据自己的特征修改父类中的属性和方法,当把这些子类当成父类来用的时候(如JAVA中的上转型对象或是接口回调),相同的父类方法就会有不同的实现方式。例如一个JAVA程序中,对于父类“动物”中的方法“叫”,用子类“狗”的上转型对象实现该方法则输出“汪汪”,用子类“猫”的上转型对象实现该方法则输出“喵喵”。

基于以上三大特点,面向对象方法导致了对整个软件开发过程的彻底变革。在软件开发的分析,设计和实现阶段都和面向过程方法截然不同。开发人员首先按照需求分析出软件的每个必备功能。然后归纳属性,确定对象及对象之间的关系。再进一步把功能分配给每个对象,构建对象的行为。接下来对每个对象的方法和对象之间的交互作进一步的细化。再接着确定可重用的类和部件,用结构图画出各个类,部件的结构和相互依赖关系。最后再对软硬件的相互依赖关系进行描述。在以上分析和设计工作完成之后,开发人员利用面向对象程序语言进行编程来达到软件功能的实现。

3 面向对象方法的优越性

面向对象方法之所以能把软件开发带入了一片新天地,是因为它在以下三个方面都有卓越之处。

3.1 整体开发思维

抛开具体操作流程不说,面向对象方法首先对解决问题的整体思维进行了人性化的革新。其人性化主要体现在以下四点:首先,人们生活的现实世界是个体,群体及各种关系组成的,面向对象的系统也是如此。对象代表个体,类代表群体,对象之间,类之间,类与对象之间通过方法调用建立各种关系。其次,从大众个体中总结出一类共同的属性和行为,从而形成类的手段正是人类抽象思维的应用。抽象思维是人类最基本,最习惯的思维之一。再次,面向对象允许开发人员一开始只拟定系统的大致框架,即确定主要的类及其关系,之后再逐步对其进行细化和拓展。这和人类逐步深入的思考习惯是相一致的。最后,面向对象方法大大简化了开发人员思考问题的复杂度。比如对于一个子类,开发人员可以理所当然的认定它已经拥有父类的所有一般特征,只要把精力放在思考子类的特性上就可以了。面向过程要求程序员必须从数据流动的角度思考待解决的问题,而面向对象的这些人性化因素让开发人员摆脱了这种被迫的“机器化”思考的尴尬境地,用自然贴切的思维考虑问题。

3.2 分析和设计

面向对象方法是分析和设计阶段的合理性有了很好的改善。面向对象的分析和设计采用的是“需求-对象-类”的模式,用对象和类直观地描述系统中的事物及其关系,这样就解决了面向过程方法所导致的一系列问题。在分析过程中,这种直观性原本的保留了所有事物及其关系的原貌,因此在构建对象和抽象出类的时候,很容易被发现在理解上的偏差。同时,开发人员也很容易向用户解释各个类和对象的含义,可以及时得到用户的反馈。处理需求的改变或是外部条件的改变时,也可以直接修改相应的类和对象。除此之外,对于问题的描述和对于问题的解决都应用同一套类和对象系统,因此软件开发的分析工作和设计工作是连续的,甚至是部分重叠的,不存在面向过程中从数据流到程序模块的转化,不用担心因为一个系统到另一个系统的映射不当导致结果和目标的偏离。

3.3 编程实现

面向对象编程语言的应用使得软件工程的实现过程有了很大的改进。

首先,程序的安全性有了明显的提高。由于类的封装,对象中只有少数的成员和方法可以被外接直接调用,对象内部的实现细节也是被隐藏的。这样有效降低了程序各部分间的依赖性,整个系统一般不会因为某处变动而引发整体混乱。

其次,面向对象把开发人员的编程工作变得比较轻松和方便。每个对象的数据和操作都被封装在一起,因此开发人员很容易保持数据和方法的兼容性,并且编程时只需要对每个类进行说明,不需把对于每个数据,每个方法的描述都写进数据字典。对于被封装的方法,只要依据访问规则就可以使用,不必了解实现细节。类中描述了一类个体的共有特征,在创建对象的时候这些描述不需要一遍又一遍的重复。类和对象的设置还易于分类,管理和查找。这些改变都在很大程度上降低了开发工作对程序员编程水平的要求。

再次,面向对象让团体合作的编程更加顺畅。归功与类和对象的直观性,当某程序员利用别人的成果时不必面临复杂的查阅,学习过程。继承性和多态性允许开发团队先行确定主要的类及关系,事先统一编程标准和风格,然后再把具体的细节交给不同的人员实现,这样最终得到的结果不会面临很多麻烦的冲突问题。

最后,面向对象语言最强大之处表现为可复用性和可扩充性。通过继承已有的类可以实现可复用性,让很多类的性质可以被共享。在开发过程中,复用自己或是他人已有的成果,等于是站在巨人的肩膀上,省去了大量的工作,加速了开发进程。另外,被重用过的代码都是经过测试的,这样大大减少了编程中发生错误的机会。面向对象的三大特点使程序具有良好的可扩充性。封装性使程序各部分间的独立性很强,继承性使类程序具有层次结构,多态性是程序能够实现问题的复杂多样。当开发人眼对已有的问题有了新的认识的时候,通过继承和多态的方式,无需修改原来的父类代码,就可以再创建新的子对象类的过程中增加新属性,或删除过时无用的属性,操作或对象,达到高效的功能扩充。可复用性和可扩充性让整个软件有很强的可维护性。在修改程序的过程中,修改某个对象对别的对象影响很小,新增或修改某功能对其他功能的影响很小。同时,开发出的软件也有很好的可移植性。对于不同的使用条件,只要修改很少的代码就可以让软件重装上阵。

4 面向对象方法的局限

虽然说面向对象方法给软件工程带来了很多好处,但是它也存在自己的局限性。第一,面向对象方法对支撑它的工具和环境的要求比较高。第二,利用对象和类对问题的描述存在不足。由于客观世界中很多事物的界限并不是很清晰,这给创建对象和抽象出类的正确性和精准性都带来了困难。并且,对于同一个客观事物,不同的人从不同的角度观察分析可能会映射出不同的对象属性和方法,有的时候开发团队之间或是开发人员与用户之间可能存在分歧。第三,面向对象程序的运行效率可能比较低,由于通过继承引入了层级,过多的祖宗类和父类势必会影响运行效率。所以在实现软件的时候应该遵循“多组合,少继承”的原则。第四,封装性带来的程序内部不可见可能给软件的维护带来不便。

由于这些局限性,在处理问题的时候不能盲目采用面向对象方法,必须先分析要解决的问题类型来决定是采用面向对象方法,面向过程方法还是其他方法,或是几种方法的综合运用。

参考文献

[1]郑莉,董源,张瑞丰.C++程序设计[M].3版.北京:清华大学出版社,2004.

[2]耿祥义,张跃平.Java面向对象程序设计[M].北京:清华大学出版社,2010.

[3]张孝祥.Java就业培训教程[M].北京:清华大学出版社,2003.

[4]杨健,张晓玲,周少云.软件危机及其应对措施探讨[J].电脑知识与技术,2006(35):135-136.

[5]符于江.程序设计中结构化方法和面向对象方法的比较[J].电脑知识与技术,2008(21):451-456.

[6]郭溪川.对比分析面向对象方法与结构化方法[J].农业网络信息,2006(11):100-104.

[7]张莉,裘国永.结构化方法与面向对象方法的比较分析[J].陕西师范大学学报:自然科学版,2006(6):29-32.

面向对象编程思想解析 篇8

面向对象的思想不仅仅局限于软件设计, 它已经拓展到更多的领域, 如分布式系统、应用平台、交互式界面、数据库系统、人工智能、嵌入式软件系统等领域。作为计算机专业的求学者和从业人员, 不管钻研或从事哪个方向的, 都应该对面向对象编程思想有所了解。

通俗地讲, 面向对象编程思想可以概括如下:系统中的一切事物都是对象;将属性和对属性执行的操作封装成为整体, 这个封装体即是对象;属性和操作相同的对象抽象成为类, 对象则是类的实体;发送消息可以使对象执行相应的操作;在现有类的基础上增加属性或操作可以构成另一个类, 这是类的继承。

2 面向过程编程思想所存在的问题

2.1 可维护性差

用传统的面向过程方法所开发出的软件, 由于可修改性较差, 维护时产生的费用仍很高, 造成其可维护性差。

2.2 重用性差

重用性指软件不用修改或略加修改就能重复使用。面向过程程序设计阶段软件重用性极差, 引起软件危机, 软件工程这一学科由此而诞生, 提高重用性是软件工程的重要目标, 而面向对象的继承机制很好地解决了软件重用性这一问题。

2.3 软件功能与用户需求不一致

用传统的结构化方法开发大型软件系统涉及各种不同领域的知识, 在开发需求模糊或需求动态变化的系统时, 所开发出的软件系统往往不能真正满足用户的需要。

3 面向对象的重要概念

3.1 类

类是属性与操作相同的对象的抽象。因此, 类是对象的抽象, 对象是类的实例。例如“人”是所有人的一个抽象的总称, 他是一个类, “鲁迅”是具体的一个人, 这就是个对象。再如“班级”是个抽象的类名, “计算机系13级软件1班”是具体的一个班级对象。

类的属性用来表示对象的各种特征, 用数据结构来描述。如长方体有三个基本属性长、宽、高;时间有三个基本属性小时、分、妙;人的基本属性有姓名、年龄、性别、工作单位等。在不同的处理需求下对于同一事物的属性描述是不一样的。

类的操作是对于对象行为的描述, 包括操作的名称和操作实现过程。

3.2 对象

对象是任何被人类研究的实物, 不管是简单的实数还是结构复杂的核潜艇都可以认为是对象。除了具体的事物, 对象还能表示抽象的规则、计划。

3.3 对象的属性和操作

对象的属性用各类数据描述。如一个餐桌的属性包括长、宽、高、材质和颜色, 前三种属性值用实型数据表示, 后两种属性值用字符串表示。对象的操作用于改变或访问对象的属性。如一个餐桌对象有一个求桌面面积的操作, 这个操作需要访问此餐桌的长和宽。对象将其属性值与操作结合在一起形成一个整体, 将这个整体封装在对象中。

3.4 消息和方法

当要求对象执行某种操作时, 必须由外界向对象发送一条消息, 消息包括对象名和方法名, 有时还要加若干参数。类中操作的实现过程叫做方法, 一个方法有方法名、参数、方法体。

3.5 类与类的特殊关系

在现实世界中存在很多类, 有些类之间是毫无关联的, 但有些类之间具有一定的特殊关系, 有两种这样的关系:继承关系和组合关系。

如果现有一个定义好的类是“人”, 还需要再定义一个“男人”类, 可以不用对“男人”类进行重新定义, 而是选择在“人”这个类的基础上增加一个性别属性即可。“人”称为父类或基类, “男人”称为子类或派生类, 这两个类的关系叫做继承, 可以说这两个类是一种“是”的关系, 即男人是人。

如果现有一个“日期”类, 还要定义一个“学生”类, 属性中要体现出生日期, 那也可以不用在“学生”类中重新定义出生日期这一属性, 可以直接用已有的“日期”类来定义生日, 这两个类的关系叫做类的组合, 可以说这两个类是一种“有”的关系, 即每个学生都有生日, 而生日是日期信息。

4 面向对象的显著特征

4.1 封装

封装很好地实现了信息隐藏, 可以达到数据保护的目的, 即对象的属性一般不被外界直接访问, 而是通过对象的方法来访问, 从而保护了对象的属性, 为软件的模块性提供了保证。另外, 类定义将外部接口 (用户可见) 与内部实现 (外界不可见) 分离, 对象的方法其内部实现细节对外界是不可见的, 用户只管调用外部接口完成对象的一系列操作。

4.2 继承

子类继承父类的所有属性和方法, 避免了许多重复性的工作, 在一个现有类的基础上新增一些属性或方法级大地减少了软件设计的工作量。继承是面向对象编程语言区别于面向过程编程语言的最显著的特点。如果子类只有一个父类称为单继承, 子类存在多个父类叫做多重继承。在软件设计工作中, 继承是信息分类与组织的切实可行的方法, 它简化了创建类的过程, 提高了软件的可重用性, 使得软件的可扩充性大大加强。

4.3 多态

多态指相同的方法作用于类型不同的对象上可以得到不一样的结果。每个对象通过满足自身意愿的方式响应同样的消息。例如在听到统一的上课铃声后, 老师们各自进入自己任课的班级, 而不是进入同一个班级, 并且所讲的内容也都不同。多态性使得软件的可重用性和灵活性进一步增强了。

5 结语

面向对象编程思想以其独特的形式将数据以及在数据之上的操作细节封装在类中, 改变了面向过程编程思路的程序结构和整体格局, 由于其继承性可以加快软件开发速度, 并增强软件可重用性, 便于软件扩充功能, 多态性可提高软件设计的灵活性, 故从过去较长时间至今一直以来仍占据着程序设计的主流地位, 也一直是衡量各层次程序员与计算机从业人员业务素质的标准。

参考文献

[1]彭莉芬、陈俊生.浅析面向对象的三大特征[J].福建电脑, 2010 (05) .

[2]谭大海、刘兴勇.面向对象分析与设计[J].科技信息, 2014 (10) .

面向对象仿真 篇9

关键词:UML,测试用例,类测试,面向对象,状态图

1 引言

面向对象软件测试的主要目标与传统软件测试目标相同,既是用最小的工作量发现最多的错误。由于面向对象所独有的多态、继承、封装等新的特点,使面向对象测试的策略和技术与传统测试有所不同,测试的视角扩大到包括复审分析和设计模型,测试焦点从模块转向类。类是构成面向对象程序的基本成分,类的测试无疑成为面向对象测试的重要环节。基于对象状态的测试是根据被测试的类的对象所处的状态以及状态之间的转移来构造测试用例,它侧重于对象的动态行为,这种动态行为依赖于对象状态。测试对象动态行为能检测出对象成员函数之间通过对象状态进行交互式产生的错误。

2 基于对象状态的测试方法的发展

现在面向对象测试中基于对象状态的测试方法一般是采用扁平状态机和状态迁移图。扁平状态机能很好的提示出一些类中的错误,但是随着类的状态属性的增加,对象状态的数目会迅速膨胀,大大增加测试的复杂度。状态转移图用于刻画对象响应各种事件时状态发生转移的情况,容易借助于自动机理论来选择测试时所用的时间序列和预测对象的状态变化结果序列,但是,它难于描述继承的对象动态行为、并发的动态行为以及由数据成员和成员函数构成的对象状态和对象状态转移。基于UML的状态图可以很好的描述对象动态行为、并发的动态行为,可以把状态的复杂度控制在和状态属性相关的线性级别,下面我们主要介绍利用UML状态图如何描述对象动态行为、并发的动态行为,以及如何产生测试用例。

3 UML状态图

UML状态图(State Diagram)是UML中对系统的动态行为进行建模的表示方法,它包括对反应型对象的行为建模。它展现了对象生命周期内可能处于的状态以及在这些状态间转换的激发条件。UML状态图中引起状态迁移的原因通常有两种,一种是在状态图中相应的迁移上未指明事件,这表示当位于迁移箭头源头的状态中的内部动作全部执行完后,该状态迁移被自动触发;另一种是,当出现某一事件时会引起状态的迁移,在状态图中把这种一起状态迁移的事件标在改前一的箭头上,如图1。

状态迁移的形式化语法为:

event_signsture[guard_condition]/action_expression^send_clause

其中事件特征event_signsture是由事件名后括号括起来的参数表组成,它指出触发迁移的事件以及与该事件相连接的附加数据。guard_condition警戒条件是一个布尔表达式,如果状态迁移中既有事件又有警戒条件,则表示仅当这个事件发生并且警戒条件为真时,触发状态迁移。动作表达式action_expression是一个触发状态迁移时可执行的过程表达式,表达式中可引用该状态所拥有的对象中的属性、操作或事件特征中的参数。发送子句send_clause是动作的一种特殊情况,用来说明在两个状态的迁移期间发送的消息。

UML状态图的优点在于它支持嵌套和并发。UML状态图中包含基本状态(basic state)和复合状态(composite state),复合状态分为或状态(or-state)和与状态(and-state)。或状态的子状态之间是相互排斥的或关系,表示在任一时刻这些子状态中只有一个子状态为真;与状态的子状态之间是并发的非相互排斥关系,与状态表示一个状态可以有多个并发的子状态,并发子状态之间用虚线分隔,用虚线分隔的每个区域表示一个并发的子状态。把状态属性看成并发的子状态,从而可以把状态图的复杂度控制在线性级别上。并发状态图中一个事件可能引起多个子状态的状态迁移。如图2中的CVM就是一个或状态,它的子状态OFF和ON之间是相互排斥的关系,ON状态就是一个与状态,当处于ON状态时,就意味着同时处于COFFEE和MONEY两个子状态。

由于UML状态图支持嵌套和并发,这就使得它比以往的状态转移图能更好的描述继承的对象动态行为、并发的动态行为以及由数据成员和成员函数构成的对象状态和对象状态转移。UML状态图中可以包含复合状态这就使得它可以把状态的复杂度控制在和状态属性相关的线性级别。下面我们讨论如何从UML状态图构造一棵复合状态测试树。

4 构造复合状态测试树

与以往的测试树不同的是复合状态测试树的每个节点代表对象的复合状态既对象的各个属性的集合,边表示状态间的迁移,根节点代表对象的初始属性集合。

构造一个队列queue来存放复合状态测试树的各个节点。

1)把UML状态图的起点读入队列queue。

2)以UML状态图的起点定义根节点Test Tree root,同时把节点标识tree Node置为对象的初始状态,nodelevel置为0,t和child Tree置为NULL,把root放入队列中。

3)取队列头部的节点设为head,搜索从head节点所对应的状态(head.tree Node)发出的状态前移以及前移置的目标状态,分别填充head.t和head.child Tree,即把迁移至的状态作为head的子节点;同时置好各个子节点的属性值,node Level=head.node Level+1,从root节点开始层次遍历测试树(从第0层至head.node Level层),如果在head的子节点中存在某个节点n,其所对应的状态已经在第0层至head.node Level层中出现过,则该节点n不再扩展,即为叶子节点。把其他没有出现过的子节点加入到队列的尾部。

4)head指向队列中的下一个节点,重复第二步,直至队列为空。

在3)中,如果某个迁移对应的目标状态已经在测试树中出现过,就不再考虑这个状态,不加入到队列尾部。这样有效地避免了重复构造节点,同时又不降低测试的覆盖率。通过上述步骤就可以构造出UML状态图对应的测试树。

复合状态树构造算法能很好的支持多个并发的子状态的情况,只是节点表示为并发子状态的合集;如果某个事件触发其他事件从而引起一系列的状态迁移时,只要把最终的状态作为节点加入到测试树中。比以往的插入桩模块更容易实现。

通过测试树可以很容易的构造出测试用例。从根节点开始沿着各个分支往下知道叶子节点,每条这样从根节点开始到某个叶子节点结束的路径上的事件按顺序组合在一起,就成为基于对象状态测试的一个测试用例。如果增加对象属性可以很容易的在复合状态测试树中增加,增加属性后可以把状态的复杂度控制在和状态属性相关的线性级别,测试时不仅可以单独的对对象的每一个属性和所有属行进行测试,也可以对对象的所有属性任意选择组合进行测试。大大增加了测试的灵活性。

5 结束语

UML的状态图支持潜逃和并发,把状态的复杂度控制在和状态属性相关的线性级别;其次UML状态参数图是在面向对象软件开发的生命周期中的早期设计阶段确定的,是对对象状态的完整的描述,并不依赖于源代码,既保证了状态描述的完整性,又可以在开发早期进行测试,尽早发现与状态相关的错误,避免将错误带入到后面的开发阶段。因此可以用UML的状态图来产生有效的测试用例,这大大提高了测试的灵活性和有效性。

参考文献

[1]张克东,庄燕滨.软件工程与软件测试自动化教程[M].北京:电子工业出版社,2002.

[2]刘金艳,蔺娟茹,尹治本.面向对象软件测试的探讨[C]//2002年全国软件与应用学术会议(NASAC)论文集.北京:机械工业出版社,2002:262-266.

[3]杨小平.面向对象软件测试探讨[J].计算机工程与应用,2000,36(1):44-46.

[4]姬莹,罗钧昊,钟联炯.面向对象软件测试主要问题的探讨[J].西安工业学院学报,2001(1).

[5]Fewster M,Graham D.软件测试自动化技术与实例详解[M].舒智勇,译.北京:电子工业出版社,2000.

[6]叶仁召,郑玉墙,鲁汉榕.面向对象软件测试及度量的研究[J].计算机工程与设计.2001,22(4):21-24.

面向对象分析方法的综述 篇10

传统的软件开发方法, 如面向过程方法和面向数据方法, 都只是针对具体问题的功能, 不允许用户需求在开发过程中有所改变。显然, 由此开发的软件系统在可靠性、可维护性和可重用性上就会存在很大的不足。为了克服传统方法的缺点, 人们在实践中创造了接近人们认识过程的面向对象的软件开发方法。面向对象方法包括面向对象分析、面向对象设计和面向对象实现。尽管面向对象方法主要用于应用系统的设计, 但面向对象分析作为一种独立的需求分析方法以及其它分析方法的补充, 目前正逐渐得到发展。

面向对象分析 (OOA:Object Oriented Analysis) 是抽取和整理用户需求并建立问题解精确模型的过程, 其分析的关键是识别出问题域内的对象, 并分析它们相互之间的关系, 最终建立问题域的简洁、精确、可理解的正确模型, 包括对象模型, 动态模型和功能模型[1], 从而为面向对象设计 (OOD) 和面向对象程序设计 (OOP) 提供指导。

近年来, 随着面向对象技术在程序设计语言、软件开发方法学、用户界面、应用集成平台、面向对象数据库、分布式系统、网络管理结构、人工智能领城以及并发工程、综合集成工程的等各领域的发展应用, 也推动了众多OOA方法的出现, 其中得到广泛认同的有Booch方法 (OOD) , Coad/Yourdon (OOA&D) , OMT, 和Jacobson (OOSE) 等方法。

现根据王晓旭划分的OOA分析方法的原则[2]和额尔敦陶克素研究的评估方法[3], 着力对影响比较大、实际中使用比较多的OOA方法进行总结、比较。

2 根据年代划分主要的OOA方法[4,5,6,7,8,9,10,11,12,13,14]

2.1 第一代:80年代

2.1.1 OOD/Booch方法

该方法是Grady Booch从1983年开始研究, 1991年后走向成熟的一种方法。Booch认为面向对象的开发是一个部分生命期的方法, 只涉及面向对象的设计和实现 (OOD和00I) , 而不涉及面向对象分析 (OOA) 。他认为应将面向对象的设计与实现和其他的需求分析方法 (如SA方法, Jackson方法等) 相结合。

Booeh方法的最大特色是将几类不同的图表有机地结合起来, 以反映系统的各个方面是如何相互联系而又相互作用的。Booch方法可分为逻辑设计和物理设计, 其中逻辑设计包含类图文件和对象图文件, 物理设计包含模块图文件和进程图文件, 用以描述软件系统结构。首先, 从逻辑设计转向物理实现的开发过程中, 有种类图表和对象图表描述逻辑设计构成中最关键的抽象及含义, 组件图表和过程图表从物理实现来描述具体的硬软件结构。

Booch方法也可划分为静态模型和动态模型。其中静态模型表示系统的构成和结构;动态模型表示系统执行的行为。动态模型包含时序图和状态转换图。

具有的符号体系:

(1) 对象图 (对象结构-静态视图) :描述实例和对象间传递消息。 (2) 类图 (类结构-静态视图) :描述类与类之间的关系。 (3) 模块图 (模块体系结构) :描述构件。 (4) 进程图 (进程体系结构) :描述进程分配处理器的情况。 (5) 状态转移图 (类结构-动态视图) :描述一个类的状态变化。 (6) 时序图 (对象结构-动态视图) :描述对象图中不同对象之间的动态交互关系。

Booch方法的实施过程如下:

(1) 在一定抽象层确定类。在问题域中, 找出关键的对象和类。 (2) 确定类和对象的含义。从外部研究类, 研究对象之间的协议。 (3) 定义类与对象的关系。 (4) 实现系统中的类与对象。 (5) 说明类的界面与实现。

2.2 第二代:80年代后期-90年代初

2.2.1 OOSA/Shlaer-Mellor方法

该方法是由Shlaer和 Mellor于1988年提出, 主要是从信息模型的经验中得来的。00sA A是以语义数据模型为基础, 因此, 与数据语义模型相似, 继承了语义数据模型详尽的关系定义和属性定义, 但对方法 (操作) 的描述不明确。类是可支持的, 但是缺乏对继承的支持, 仅仅是支持对象属性的继承, 而不支持服务 (操作) 继承, 也不明确支持软件重用。OOSA只是隐含类、继承和封装这3个基本原则。

OOSA 以语义数据模型为基础, 从对象的结构、操作和生命周期角度建立信息模型、过程模型和状态模型, 并在这3种模型的建模活动中得到一系列比较清晰的图表。

实现的步骤:

(1) 定义信息模型:由对象、属性、关系和多个对象结构所组成。 (2) 定义对象的生命周期:分析各个对象的生命周期, 并将生命周期规范化为状态、事件、事务规划和行为的集合。 (3) 定义关系动态:为对象之间的动态关系建立状态模型。 (4) 定义系统动态:该步骤产生系统级的控制模型, 对象-通讯模型用于异步控制, 对象-存取模型用于同步控制。 (5) 定义处理模型:对于每个行为, 建立一个行为-数据流图。行为-数据流图描述对于行为的一切处理, 同时也描述处理中的数据流和数据存储。 (6) 定义范围和子系统:对于一个大的系统, 将其中的主要事件从概念上区分它们的范围并将大系统划分为若干个子系统是非常必要的。

OOSA缺乏对继承的支持, 适用于分析阶段和实时系统;OOSA实际上只是一种分析方法, 因此, 主要用于开发实时系统。

2.2.2 RDD/Wirfs-Brock

该方法是Wirfs-Brock在1990年提出的。其核心在于引入了拟人化的思想, 把对象的行为处理成该对象应负的责任、把对象间的关系处理为人类相互之间的合作形式, 发生相互关系的对象在系统中分别扮演客户与服务者的角色。客户对象以合约的形式向服务者对象提出服务请求, 服务者对象有责任提供客户所要求的服务, 而合约详细地规定了所需服务的操作细节。

RDD 方法先是定义系统的类和对象, 然后在确定系统的责任后将其划分给类, 最后确定对象类之间的合作来完成类的责任。设计过程再按照类的层次、子系统和协议进一步完善。分为探索阶段和精化阶段:

(1) 探索阶段:确定类、每个类的责任以及类间的合作。 (2) 精化阶段:精化类继承层次、确定子系统、确定协议。

RDD按照类层次图、合作图、类规范、子系统规范、合同规范等设计规范来完成实现。

2.2.3 OOAD/Coad-Yourdon方法

由Peter Coad和Edward Yourdon在1991年提出的, 是一种逐步进阶的面向对象建模方法, 适用于小型系统的开发。Coad-Yourdon方法严格区分了面向对象分析和面向对象设计。该方法利用五个层次和活动定义和记录系统行为, 输入和输出。这五个层次的活动包括:发现类及对象、识别结构、定义主题、定义属性和定义服务。

面向对象分析 (主要用于完成系统分析) 。

(1) 定义主题:发现并标识对象与类:进行类及对象的发现及描述。 (2) 标识服务:目的在于定义对象的行为之间的消息链接。 (3) 标识结构:包括上述的一般/特殊结构和局/部分结构。 (4) 标识属性:对于每个对象, 都需要找出在目标系统中对象所需要的属性, 而后将属性安排到适当的位置, 找出实例链接, 最后进行检查。

面向对象设计 (主要负责系统设计) 。

(1) 设计数据管理子系统:核心是数据存储, 常用的存储技术有文件管理、关系数据库管理和面向对象数据库管理。 (2) 设计任务管理子系统:主要是对系统各种任务进行选择和调整的过程。 (3) 构建问题域子系统:对分析的问题域模型进行需求调整、类的重用、增加一般化类建立协议等。 (4) 设计人机交互子系统:包括用户界面风格, 命令结构层次关系等内容的设计。

这种方法, 概念简单, 易于掌握。但是对每个对象的功能和行为的描述不很全面, 对象模型的语义表达能力不是太强。

2.2.4 OMT/Rumbaugh方法

OMT (Object Modeling Technique) 方法提出于1987年, 1991年Jim Rumbaugh正式把OMT应用于面向对象的分析和设计, 这种方法是在实体关系模型上扩展类、继承和行为而得到的。OMT方法的中心思想就在于从三个不同的角度和观点对所要考虑的系统进行建模, 即建立对象模型、动态模型和功能模型。

(1) 对象模型:描述系统的静态结构, 该模型主要关心系统中对象的结构、属性和操作。

(2) 动态模型:描述系统的控制结构, 表示了瞬时的行为化的系统控制性质, 它从对象的时间和状态角度出发, 表现对象的相互行为。

(3) 功能模型:描述了系统的所有功能操作。在该模型中说明对象模型操作的含义、动态模型中动作的意义及对象模型中约束的意义。

OMT方法全面覆盖了软件开发的整个过程, 包括分析、设计和实现几个步骤:

(1) 分析:基于问题和用户需求的描述, 建立现实世界的模型。

分析阶段的产生:问题描述、对象模型=对象图+数据词典、动态模型=状态图+全局事件流图、功能模型=数据流图+约束。

(2) 系统设计:结合问题域的知识和目标系统的体系结构将目标系统分解为子系统。

(3) 对象设计:基于分析模型和求解域中的体系结构等添加的实现细节, 完成系统设计。主要产物包括:细化的对象模型、细化的动态模型、细化的功能模型。

(4) 实现:将设计转换为特定的编程语言或硬件, 同时保持可追踪性、灵活性和可扩展性。

OMT方法通过构造三个模型较全面地描述了系统的需求, 但在功能模型中使用数据流图与其它两个模型有些脱节。

2.2.5 Bailin

Bailin认为从面向过程的分析到面向对象的设计开发需要对数据流图进行重大修改, 因此, 提出了一个面向对象的需求定义方法:使用了一种专门的语言将实体数据流图 (EDFD) 和实体关系图 (ERD) 组合到一起。该方法没有明显的面向对象的术语 (如, 类、对象、属相等) , 但它遵循OO的基本原则:实体关系图中既包含了对象的类和继承的概念, 也包含了OO中封装的既念。

实现过程:

(1) 定义实体:画出数据流程图, 给出出现在处理过程中的实体的名称。

(2) 区别激活的与惰态的实体:区别对系统需求描述重要的或非重要的实体, 构造一个实体关系图 (ERD) 。

(3) 建立激活实体间的数据流:构造一个最高一级的实体数据流图 (EDFD) 。每个激活的实体作为一个处理节点, 每个惰态实体为一个数据流或数据存储。

(4) 分解实体/功能:在各个分解步骤中, 应考虑各个新的子实体是否被包含在新的子功能中。

(5) 修改实体状态:确定新的实体的状态, 并重新组织EDFD。

2.3 第三代:90年代中期

2.3.1 VMT (Visual Modeling Technique)

该方法结合了OMT、OOSE、RDD等方法的优点, 并且结合了可视化编程和原型技术。VMT选择OMT作为整个方法的框架, 并且采用OMT的表示方法, 但抛弃了OMT中的采用数据流图描述的功能模型, 代之以RDD方法中的CRC (Class Responsibility Collaboration) 卡片, 用它来描述对象的操作和对象间的关系。VMT 还引入了OOSE中的使用事例概念, 用来描述用户对系统的需求, 从而获得更准确的用户需求模型。

开发过程:分为分析、设计和实现3个阶段。

(1) 分析阶段:主要任务是建立分析模型, 即, 将用户需求结构化并形式化, 这个阶段的产品描述未来的系统应该做什么, 而不描述怎么去做。

(2) 设计阶段:目标是制定解决问题的策略, 为实现解决方案打下整体基础, 并寻求把设计要素转换成解决方案的切实可行的方法, 该阶段包括系统设计、对象设计和永久性对象设计。

(3) 实现阶段:用某一种环境来实现系统, 完成从对象设计模型到解决方案的影射过程。

IBM公司在提出VMT 的同时, 推出了支持VMT的可视化编程工具VisualAge , 用它可以很容易地实现设计阶段建立的模型。

3 7种面向对象分析方法的比较

3.1 根据抽象原则

每种OOA方法都使用抽象原则, 以便从系统需求获取重要部分而将次要部分忽略掉。然而, 这种原则都有不同的侧重点:

数据抽象侧重于数据方面;

过程抽象侧重于过程方面;

事件抽象侧重于系统的事件方面。

1种OOA方法所采用的抽象原则可以有1个, 2个或3个侧重点。表1列出了7种方法中抽象原则的侧重点。

3.2 比较7种方法的覆盖边界

目前, OOA和OOD方法的边界划分上尚存在着争议。如, 有人认为面向对象软件开发过程可以分为面向对象分析、面向对象设计和面向对象程序设计三个阶段;有人认为分析和设计可以交叉进行不必做严格区分;还有人沿用传统方法进行分析和设计, 用面向对象程序设计语言来实现系统。

现就上述方法的实现过程, 将其边界问题进行尝试性的划分。

4 结语

除上述方法外, 还有Beard、Firesmith、Martin-Odell等面向对象分析的方法, 但OMT方法、Coad-Yourdon方法和Booch方法被列为OO软件开发的三个重要流派。对OOA方法的分类也遵循很多原则, 如, 费翔林[15]就按照以非形式化规格说明为基础、以结构化方法为基础和以语义数据模型为基础综述了OOA方法。

总之, 在前人的基础上对面向对象分析方法进行了简单的分类、比较研究, 以期为选择面向对象方法以及创建新OOA方法提供一些依据。

摘要:将7种主要的OOA方法按照提出的年代进行划分, 并在简单介绍的基础上, 依据抽象原则和边界的划分 (面向对象分析和面向对象设计的划分) , 并对7种方法进行了比较研究, 以期为选择面向对象方法以及创建新的OOA方法提供一些依据。

上一篇:安全生产措施费下一篇:改良式体位引流