本节将介绍主要软件开发方法。
1977年出现的结构化方法学也称为生命周期方法学,它采用结构化技术(结构化分析、结构化设计和结构化实现)来完成软件开发的各项任务。这种方法学把软件生命周期的全过程依次划分为若干个阶段,然后顺序地完成每个阶段的任务。
结构化方法学具有以下特点。
● 阶段性。前一阶段工作完成以后,后一阶段工作才能开始,前一阶段的输出文档是后一阶段的输入文档。
● 推迟实施。将分析和设计阶段与实施分开,适当地推迟系统的具体程序实现。
● 文档管理。在每阶段就规定了要完成的文档资料,没有完成文档,就认为没有完成该阶段的任务。在每一阶段都要对已完成的文档进行复审,以便尽早发现问题,避免后期的返工。
把软件生命周期划分成若干个阶段,每个阶段的任务相对独立,而且比较简单,便于不同人员分工协作,从而降低了整个软件开发过程的困难程度;在每个阶段结束之前都要从技术和管理两个角度进行严格的审查,合格之后才开始下一阶段的工作,这就使软件开发的全过程以一种有条不紊的方式进行。
结构化方法学曾经给软件产业带来巨大进步,在一定程度上缓解了软件危机。但结构化方法基于功能分析与功能分解,软件结构紧密依赖于系统功能,而在实际开发工作中,系统功能往往又是模糊易变的,功能的变化经常会引起软件结构的整体修改。
目前,面向对象方法已取代结构化方法成为软件方法学的主流。但对于一些功能需求非常明确而且不会轻易改变的软件系统,结构化方法仍然是比较有效的。
结构化分析(Structured Analysis,SA)方法是一种面向数据流的需求分析方法。它的基本思想是自顶向下逐层分解,把一个大问题分解成若干个小问题,每个小问题再分解成若干个更小的问题。经过逐层分解,每个最低层的问题都是足够简单、容易解决的,于是复杂的问题也就迎刃而解了。
数据流图和数据字典是结构化分析的常见工具,软件需求说明书是需求分析阶段的最后成果。
数据流图(Data Flow Diagram,DFD)用来描述数据流从输入到输出的变换流程。关于更多详细的内容参见“数据流图设计”的内容。
数据字典是关于数据的信息的集合,也就是对数据流图中包含的所有元素的定义的集合。
数据流图和数据字典共同构成系统的逻辑模型。没有数据流图,数据字典难以发挥作用;没有数据字典,数据流图就不严格。只有把数据流图和对数据流图中每个元素的精确定义放在一起,才能共同构成系统的规格说明。关于更多详细的内容参见“数据设计”的内容。
系统设计是软件生命周期的重要组成部分,主要包括体系结构设计、接口设计、数据设计和过程设计。
结构化设计(Structured Design,SD)方法是一种面向数据流的设计方法,它是以结构化分析阶段所产生的文档(包括数据流图、数据字典和软件需求说明书)为基础,自顶向下,逐步求精和模块化的过程。结构化设计通常可分为概要设计和详细设计。概要设计的任务是确定软件系统的结构,进行模块划分,确定每个模块的功能、接口及模块间的调用关系。详细设计的任务是为每个模块设计实现的细节。更多详细的内容参见“软件设计概述”的内容。
经过需求分析阶段的工作,系统必须已经清楚了“做什么”,概要设计的基本目的就是回答“概括地说,系统应该如何实现?”这个问题。概要设计的重要任务就是设计软件的结构,也就是要确定系统是由哪些模块组成的,以及这些模块相互间的关系。
SD方法采用结构图(structure chart)来描述程序的结构。构成程序结构图的主要成分有模块、调用和数据,结构图中的模块用矩形表示,在矩形框内可标上模块的名字。模块间如有箭头或直线相连,表明它们之间有调用关系。SD方法有时也使用层次图和HIPO图(层次图加输入/处理/输出图)。
整个概要设计过程主要包括:
第1步:复查基本系统模型。复查的目的是确保系统的输入数据和输出数据符合实际。
第2步:复查并精化数据流图。应该对需求分析阶段得到的数据流图认真复查,并且在必要时进行精化。不仅要确保数据流图给出了目标系统的正确的逻辑模型,而且应该使数据流图中每个处理都代表一个规模适中相对独立的子功能。
第3步:确定数据流图的信息流类型。数据流图中从系统的输入数据流到系统的输出数据流的一连串连续变换形成了一条信息流。信息流大体可分为两种类型:
● 变换流:信息沿着输入通道进入系统,然后通过变换中心(也称主加工)处理,再沿着输出通道离开系统。具有这一特性的信息流称为变换流。具有变换流型的数据流图可明显地分成输入、变换(主加工)、输出三大部分。
● 事务流:信息沿着输入通道到达一个事务中心,事务中心根据输入信息(即事务)的类型在若干个动作序列(称为活动流)中选择一个来执行,这种信息流称为事务流。事务流有明显的事务中心,各活动以事务中心为起点呈辐射状流出。
第4步:根据流类型分别实施变换分析或事务分析。变换分析是从变换流型的数据流图导出程序结构图。具体过程如下。
● 确定输入流和输出流的边界,从而孤立出变换中心。
● 完成第一级分解,设计模块结构的顶层和第一层。
● 完成第二级分解,也就是输入控制模块、变换控制模块和输出控制模块的分解,设计中、下层模块。
事务分析是从事务流型的数据流图导出程序结构图,具体过程如下:
● 确定事务中心和每条活动流的流特性。
● 将事务流型数据流图映射成高层的程序结构,分解出接收模块、发送模块(调度模块),以及发送模块所控制的下层所有的活动流模块。
● 进一步完成接受模块和每一个活动流模块的分解。
第5步:根据软件设计原则对得到的软件结构图进一步优化。
概要设计已经确定了每个模块的功能和接口,详细设计的任务就是为每个模块设计其实现的细节。详细设计阶段的根本目标是确定应该怎样具体地实现所要求的系统,得出对目标系统的精确描述。
结构化程序设计(Structured Programming,SP)采用自顶向下逐步求精的设计方法和单入口单出口的控制结构。在设计一个模块的实现算法时先考虑整体后考虑局部,先抽象后具体,通过逐步细化,最后得到详细的实现算法。单入口单出口的控制结构使程序的静态结构和动态执行过程一致,具有良好的结构,增强了程序的可读性。
针对在程序中大量无节制地使用GOTO语句而导致程序结构混乱的现象,Dijkstra于1965年提出在程序语言中取消GOTO语句。1966年,Bohm和Jacopini证明了任何单入口、单出口、没有死循环的程序都能用3种基本的控制结构来构造,这3种基本的控制结构是:顺序结构、IF_THEN_ELSE型分支结构(选择结构)和DO_WHILE型循环结构。如果程序设计中只允许使用这三种基本的控制结构,则称为经典的结构化程序设计;如果还允许使用DO_CASE型多分支结构和DO_UNTIL型循环结构,则称为扩展的结构化程序设计;如果再加上允许使用LEAVE(或BREAK)结构,则称为修正的结构化程序设计。
应用于详细设计的工具主要包括以下几种。
● 程序流程图:程序流程图又称为程序框图,它是历史最悠久的描述过程设计的方法,然而它也是用得最混乱的一种方法。程序流程图的主要优点是对控制流程的描绘很直观,便于初学者掌握。但由于程序流程图中用箭头代表控制流,经常诱使程序员不顾结构化程序设计的精神而随意转移控制,且不支持逐步求精方法,不易表现数据结构。程序流程图尽管有种种缺点,许多人建议停止使用它,但至今仍在广泛使用着。不过总的趋势是越来越多的人不再使用程序流程图了。
● 盒图(N–S图):盒图是由Nassi和Shneiderman提出的一种符合结构化设计原则的图形描述工具,它仅含五种基本的控制结构:顺序结构、IF-THEN-ELSE型分支结构、CASE型多分支结构、DO-WHILE和DO-UNTIL型循环结构、子程序结构。盒图具有以下特点。
▶ 功能域(即一个特定控制结构的作用域)明确,可以从盒图上一眼就看出来。
▶ 由于没有箭头,不可能任意转移控制。
▶ 容易确定局部和全程数据的作用域。
▶ 容易表示嵌套关系,也可以表示模块的层次结构。
坚持使用盒图作为详细设计的工具,可以使程序员逐步养成用结构化的方式思考问题和解决问题的习惯。
● PAD图:PAD图是问题分析图(Problem Analysis Diagram)的英文缩写,它用二维树型结构的图表示程序的控制流,比较容易翻译成机器代码。PAD图具有以下特点。
▶ 使用表示结构化控制结构的PAD符号所设计出来的程序必然是结构化程序。
▶ PAD图所描绘的程序结构十分清晰。
▶ 用PAD图表现程序逻辑,易读、易懂、易记。
▶ 容易将PAD图转换成高级语言源程序,这种转换可用软件工具自动完成。
▶ PAD图既可表示程序逻辑,也可用于描绘数据结构。
▶ PAD图的符号支持自顶向下、逐步求精方法的使用。
● PDL:PDL是程序设计语言(Program Design Language)的英文缩写,也称伪码,是一种以文本方式表示数据和处理过程的设计工具。PDL是一种非形式化语言,它对控制结构的描述是确定的,但控制结构内部的描述语法是不确定的,它可根据不同的应用领域和不同的设计层次灵活选用其描述方式,甚至可用自然语言描述。与程序语言(Programming Language)不同,PDL程序是不可执行的,但它可以通过转换程序自动转换成某种高级程序语言的源程序。
常见的详细设计工具还包括判定树、判定表等。
上面讲的结构化设计方法是面向数据流的,另外还有一种面向数据结构的设计方法。它根据输入/输出数据结构导出程序结构。
在许多应用领域中信息都有清楚的层次结构,输入数据、内部存储的信息(数据库或文件)及输出数据都可能有独特的结构。数据结构既影响程序的结构,又影响程序的处理,重复出现的数据通常由具有循环控制结构的程序来处理,选择数据(即可能出现也可能不出现的信息)要用带有分支控制的程序来处理。层次的数据组织通常和使用这些数据的程序的层次结构十分相似。面向数据结构设计方法的基本思想就是根据数据结构导出程序结构。
Jackson方法和Warnier方法是最著名的两种面向数据结构的设计方法。
Jackson方法的基本步骤是:建立系统的数据结构;以数据结构为基础,对应地建立程序结构;列出程序中要用到的各种基本操作,再将这些操作分配到程序结构适当的模块中。
Warnier方法不再详细介绍。
由于面向数据结构的设计方法并不明显地使用软件结构的概念,对于模块独立原则也没有给予应有的重视,因此并不适合于复杂的软件系统。
软件设计包括4个既独立又相互联系的活动,分别为 (32) 、 (33) 、数据设计和过程设计。
(32)A.用户手册设计 B.语言设计 C.体系结构设计 D.文档设计
(33)A.文档设计 B.程序设计 C.实用性设计 D.接口设计
例题分析:
软件设计包括体系结构设计、接口设计、数据设计和过程设计。
例题答案 :(32)C (33)D
如图4-7中的程序由A、B、C、D、E 5个模块组成,如表4-12中描述了这些模块之间的接口,每—个接口有一个编号。此外,模块A、D和E都要引用一个专用数据区。那么A和E之间耦合关系是_______。
图4-7 模块构成示意图
表4-12 说明表
(32)A.公共耦合 B.数据耦合 C.内容耦合 D.无耦合
例题分析:
模块的耦合性类型通常分为7种,根据耦合度从低到高排序如表4-13所示。
表4-13 耦合性概念表
(续表)
对照表4-13,我们不难发现,A与E之间的关系为:“多个模块引用同一个全局数据区”。所以为公共耦合。此题答案为A。
例题答案: A
结构化开发方法中,数据流图是____阶段产生的成果。
A.需求分析 B.总体设计 C.详细设计 D.程序编码
例题分析
结构化分析是面向数据流进行需求分析的方法,数据流图是分析过程中用来描述数据处理过程的工具。它从数据传递和加工的角度,以图形的方式刻画数据流从输入到输出的移动变换过程,是对软件所要处理数据的抽象。由于数据流图只反映系统必须完成的逻辑功能,所以它是一种功能模型。
例题答案: A
通常在软件的____活动中无须用户参与。
A.需求分析 B.维护 C.编码 D.测试
例题分析:
在软件开发的过程中,要求用户参与的活动有:系统分析、软件项目计划、需求分析、软件测试、软件维护。在编码阶段只有高级程序员和程序员参与。
例题答案: C
内聚性和耦合性是度量软件模块独立性的重要准则,软件设计时应力求___。
A.高内聚,高耦合 B.高内聚,低耦合 C.低内聚,高耦合 D.低内聚,低耦合
例题分析:
在软件设计时,对软件模块独立性通常提出高内聚,低耦合,原因是:
● 高耦合度的系统是很难维护的。一处的修改引起另一处甚至更多处的变动。你可以通过以下方法降低程序的耦合度:隐藏实现细节,强制构件接口定义,不使用公用数据结构,不让应用程序直接操作数据库。耦合度低的软件可以很容易被重用、维护和扩充。
● 高内聚性的软件更容易维护和改进。判断一个模块是否有高的内聚性,看一看你是否能够用一个简单的句子描述它的功能就行了。如果你用了一段话或者你需要使用类似“和”、“或”等连词,则说明你需要-将该模块细化。 只有高内聚性的模块才可能被重用。
例题答案: B
______是一种面向数据流的开发方法,其基本思想是软件功能的分解和抽象。
A.结构化开发方法 B.Jackson系统开发方法 C.Booch 方法 D.UML(统一建模语言)
例题分析:
本题考查软件工程的结构化开发方法,是常考的知识点。
结构化开发方法 (Structured Method,结构化方法)是强调开发方法的结构合理性,以及所开发软件的结构合理性的软件开发方法。结构是指系统内各个组成要素之间的相互联系、相互作用的框架。结构化开发方法提出了一组提高软件结构合理性的准则,如分解与抽象、模块独立性、信息隐蔽等。针对软件生存周期各个不同的阶段,它有结构化分析(SA)、结构化设计(SD)和结构化程序设计(SP)等方法。它的基本思想:把一个复杂问题的求解过程分阶段进行,每个阶段处理的问题都控制在人们容易理解和处理的范围内。
Jackson 系统开发方法 (JSD,Jackson System Development)是一种典型的面向数据结构的分析设计方法。Jackson系统开发方法的系统模型就是相互通信的一组进程的集合。进程间的通信方式有以下3种。
● 进程同步发生。
● 通过数据通道发送/接收活动发生。
● 访问公用存储信息。
Booch 最先描述了面向对象的软件开发方法的基础问题,指出面向对象开发是一种根本不同于传统的功能分解的设计方法。面向对象的软件分解更接近人对客观事务的理解,而功能分解只通过问题空间的转换来获得。
UML (统一建模语言) 软件工程领域在1995年—1997年取得了前所未有的进展,其成果超过软件工程领域过去15年的成就总和,其中最重要的成果之一就是统一建模语言(UML)的出现。UML将是面向对象技术领域内占主导地位的标准建模语言。
UML不仅统一了Booch方法、OMT方法、OOSE方法的表示方法,而且对其做了进一步的发展,最终统一为大众接受的标准建模语言。UML是一种定义良好、易于表达、功能强大且普遍适用的建模语言。它融入了软件工程领域的新思想、新方法和新技术。它的作用域不限于支持面向对象的分析与设计,还支持从需求分析开始的软件开发全过程。
所以本题中涉及面向数据流的开发方法,其基本思想是软件功能的分解,抽象开发方法是结构化开发方法。
例题答案: A
结构化分析和设计方法在一定程度上缓解了“软件危机”。但随着人们对软件提出的要求越来越高,结构化方法已经无法承担快速高效开发复杂软件系统的重任。20世纪80年代逐渐成熟的面向对象方法学,使软件开发者对软件的分析、设计和编程等方面都有了全新的认识。由于“对象”概念的引入,将数据和方法封装在一起,提高了模块的聚合度,降低了模块的耦合度,更大程度上支持了软件重用,从而十分有效地降低了软件的复杂度,提高了软件开发的生产率。目前,面向对象方法学已成为软件开发者的第一选择。
究竟怎样才算真正的“面向对象”(Object-Oriented,OO)?Peter Coad和Edward Yourdon提出了下列等式:
对象(Object)是系统中用来描述客观事物的一个实体,它是构成系统的一个基本单位。面向对象的软件系统是由对象组成的,复杂的对象由比较简单的对象组合而成。也就是说,面向对象方法学使用对象分解取代了传统方法的功能分解。
对象三要素对象标识、属性和服务。
对象标识(Object Identifier),也就是对象的名字,供系统内部唯一地识别对象。定义或使用对象时,均应指定对象标识。
属性(Attribute),也称状态(State)或数据(Data),用来描述对象的静态特征。在某些面向对象的程序设计语言中,属性通常被称为成员变量(Member Variable)或简称变量(Variable)。
服务(Service),也称操作(Operation)、行为(Behavior)或方法(Method)等,用来描述对象的动态特征。在某些面向对象的程序设计语言中,服务通常被称为成员函数(Member Function)或简称函数(Function)。
封装(Encapsulation)是对象的一个重要原则。它有两层含义:第一,对象是其全部属性和全部服务紧密结合而形成的一个不可分割的整体;第二,对象是一个不透明的黑盒子,表示对象状态的数据和实现操作的代码都被封装在黑盒子里面。使用一个对象的时候,只需知道它向外界提供的接口形式,无须知道它的数据结构细节和实现操作的算法。从外面看不见,也就更不可能从外面直接修改对象的私有属性了。
类(Class)是对具有相同属性和服务的一个或一组对象的抽象定义。
类与对象是抽象描述与具体实例的关系,一个具体的对象被称做类的一个实例(instance)。
继承(Inheritance)是面向对象方法学中的一个十分重要的概念,其定义是:特殊类(或称子类、派生类)的对象拥有其一般类(或称父类、基类)的全部属性与服务,称做特殊类对一般类的继承。在面向对象的方法学中,继承是提高软件开发效率的重要原因之一。
多态性(Polymorphism)是指一般类中定义的属性或服务被特殊类继承之后,可以具有不同的数据类型或表现出不同的行为。使用多态技术时,用户可以发送一个通用的消息,而实现的细节则由接受对象自行决定,这样同一消息就可以调用不同的方法。多态性不仅增加了面向对象软件系统的灵活性,进一步减少了信息冗余,而且显著提高了软件的可重用性和可扩充性。多态有多种不同的形式,其中参数多态和包含多态称为通用多态,过载多态和强制多态称为特定多态。
消息(Message)就是向对象发出的服务请求,它应该含有下述信息:提供服务的对象标识、消息名、输入信息和回答信息。对象与传统的数据有本质区别,它不是被动地等待外界对它施加操作,相反,它是进行处理的主体,必须发消息请求它执行它的某个操作,处理它的私有数据,而不能从外界直接对它的私有数据进行操作。
消息通信(Communication With Messages)也是面向对象方法学中的一条重要原则,它与对象的封装原则密不可分。封装使对象成为一些各司其职、互不干扰的独立单位;消息通信则为它们提供了唯一合法的动态联系途径,使它们的行为能够互相配合,构成一个有机的系统。
只有同时使用对象、类、继承与消息通信,才是真正面向对象的方法。
● 与人类习惯的思维方法一致:面向对象方法学的出发点和基本原则,是尽可能模拟人类习惯的思维方式,使软件开发的方法与过程尽可能接近人类认识世界解决问题的方法与过程,也就是使描述问题的“问题域”与解决问题的“解域”在结构上尽可能一致。
● 稳定性好:传统的软件开发方法基于功能分析与功能分解,软件结构紧密依赖于系统所要完成的功能,当功能需求发生变化时将引起软件结构的整体修改。而用户需求变化大部分是针对功能的,因此这样的系统是不稳定的。
面向对象的方法用对象模拟问题域中的实体,以对象为中心构造软件系统,系统的功能需求变化时并不会引起软件结构的整体变化。由于现实世界中的实体是相对稳定的,因此以对象为中心构造的软件系统也是比较稳定的。
● 可重用性好:面向对象方法学在利用可重用的软件成分构造新的软件系统时有很大的灵活性。继承机制与多态性使得子类不仅可以重用其父类的数据结构与程序代码,并且可以方便地修改和扩充,而这种修改并不影响对原有类的使用。
● 较易开发大型软件产品:用面向对象方法学开发软件时,构成软件系统的每个对象相对独立。因此,可以把一个大型软件产品分解成一系列相互独立的小产品来处理。这不仅降低了开发的技术难度,而且也使得对开发工作的管理变得容易多了。
● 可维护性好:面向对象的软件比较容易理解、容易修改、容易测试。
综观计算机软件发展史,许多新方法和新技术都是在编程领域首先兴起,进而发展到软件生命周期的前期阶段——分析与设计阶段。结构化方法经历了从“结构化编程”、“结构化设计”到“结构化分析”的发展历程,面向对象的方法也经历了从“面向对象的编程”(Object-Oriented Programming,OOP)、“面向对象的设计” (Object-Oriented Design,OOD)到“面向对象的分析”(Object-Oriented Analysis,OOA)的发展历程。1989年之后,面向对象方法的研究重点开始转向软件生命周期的分析阶段,并将OOA和OOD密切地联系在一起,出现了一大批面向对象的分析与设计(OOA&D)方法。截止到1994年,公开发表并具有一定影响的OOA&D方法已达50余种。
由于各种OOA方法所强调的重点与该方法的主要特色不同,因此所产生的OOA模型从整体形态、结构框架到具体内容都有较大的差异。
1991年,James Rumbaugh在《面向对象的建模与设计》(Object-Oriented Modeling and Design)一书中提出了面向对象分析与设计的OMT(Object Modeling Technique)方法。20世纪90年代中期,笔者曾使用OMT方法开发了“印典”、“书林”等排版系统。本书的OOA模型主要依据OMT方法,同时参考了Peter Coad和Edward Yourdon的OOA模型。
OMT方法的OOA模型包括对象模型、动态模型和功能模型。
对象模型表示静态的、结构化的系统的“数据”性质。它是对模拟客观世界实体的对象及对象彼此间的关系的映射,描述了系统的静态结构。通常用类图表示。
动态模型表示瞬时的、行为化的系统的“控制”性质,它规定了对象模型中的对象的合法变化序列。通常用状态图表示。
功能模型表示变化的系统的“功能”性质,它指明了系统应该“做什么”,因此更直接地反映了用户对目标系统的需求。通常用数据流图表示。
OMT方法的三个模型,分别从三个不同侧面描述了所要开发的系统:功能模型指明了系统应该“做什么”;动态模型明确了什么时候做(即在何种状态下接受了什么事件的触发);对象模型则定义了做事情的实体。这三种模型相互补充、相互配合,三者之间具有下述关系:
● 动态模型展示了对象模型中每个对象的状态及它接受事件和改变状态时所执行的操作;而功能模型中的处理则对应于对象模型中的对象所提供的服务。
● 对象模型展示了动态模型中是谁改变了状态和经受了操作;而功能模型中的处理则可能产生动态模型中的事件。
● 对象模型展示了功能模型中的动作者、数据存储和流的结构;而动态模型则展示了功能模型中执行加工的顺序。
Peter Coad和Edward Yourdon在1991年出版的《面向对象的分析》(Object-Oriented Analysis)一书中指出,复杂系统的对象模型通常由下述五个层次组成:类及对象层、结构层、主题层、属性层和服务层。上述五个层次对应着建立对象模型的五项主要活动:确定类与对象、确定结构与关联、划分主题、定义属性和定义服务。但这五项活动完全没必要顺序完成,也无须彻底完成一项活动之后再开始另外一项活动。
● 确定类与对象:类与对象是在问题域中客观存在的,系统分析的重要任务之一就是找出这些类与对象。首先找出所有候选的类与对象,然后进行反复筛选,删除不正确或不必要的类与对象。
●确定结构与关联:结构与关联反应了对象(或类)之间的关系,主要有以下几种:
▶ 一般–特殊结构(Generalization-Specialization Structure),又称分类结构(Cassification Structure),是由一组具有一般–特殊关系(继承关系)的类所组成的结构。一般–特殊关系(Generalization-Specialization Relation)的表达式为:is a kind of。
▶ 整体–部分结构(Whole-Part Structure),又称组装结构(Composition Structure),是由一组具有整体–部分关系(组成关系)的类所组成的结构。整体–部分关系(Whole-Part Relation)的表达式为:has a。
▶ 实例关联(Instance Connection),即一个类的属性中含有另一个类的实例(对象),它反映了对象之间的静态联系。
▶ 消息关联(Message Connection),即一个对象在执行自己的服务时需要通过消息请求另一个对象为它完成某个服务,它反映了对象之间的动态联系。
● 划分主题:在开发大型、复杂软件系统的过程中,为了降低复杂程度,需要把系统划分成几个不同的主题。注意,应该按问题域而不是用功能分解方法来确定主题,应该按照使不同主题内的对象相互间依赖和交互最少的原则来确定主题。
● 定义属性:为了发现对象的属性,首先考虑借鉴以往的OOA结果,看看相同或相似的问题域是否有已开发的OOA模型,尽可能复用其中同类对象的属性定义。然后,按照问题域的实际情况,以系统责任为目标进行正确的抽象,从而找出每一对象应有的属性。
● 定义服务:发现和定义对象的服务,也应借鉴以往同类系统的OOA结果并尽可能加以复用。然后,研究问题域和系统责任以明确各个对象应该设立哪些服务,以及如何定义这些服务。
建立动态模型的第一步,是编写典型交互行为的脚本。虽然脚本中不可能包括每个偶然事件,但至少必须保证不遗漏常见的交互行为。第二步,从脚本中提取出事件,确定触发每个事件的动作对象及接受事件的目标对象。第三步,排列事件发生的次序,确定每个对象可能有的状态及状态间的转换关系,并用状态图描绘它们。最后,比较各个对象的状态图,检查它们之间的一致性,确保事件之间的匹配。
OMT方法中的功能模型实际上就是结构化方法中的数据流图。从这点看,OMT方法并不是“纯”面向对象的。这是OMT方法的一大缺陷。
1992年,Ivar Jacobson在《面向对象的软件工程——用例驱动的途径》(Object-Oriented Software Engineering,A Use Case Driven Approach)中首次提出了“用例”(use case)的概念。随后,有人提出以用例图取代数据流图进行需求分析和建立功能模型,这应该被看做是对OMT方法的重大改进。使用用例图建立起来的系统模型也被称为用例模型。
一个用例是可以被行为者感受到的、系统的一个完整的功能。一幅用例图包含的模型元素有系统、行为者、用例及用例之间的关系。用例模型描述的是外部行为者所理解的系统功能。
目前,“用例驱动”已成为软件开发过程的一条重要原则。
与结构化方法不同,面向对象的方法并不强调分析与设计之间严格的阶段划分。OOA与OOD所采用的概念、原则和表示法都是一致的,二者之间不存在鸿沟,不需要从分析文档到设计文档的转换,所以有些工作无论在分析时进行还是在设计时进行都不存在障碍。当然,OOA与OOD仍然有不同的分工和侧重点。
关于OOA与OOD的关系,目前有两种不同的观点。
一种观点是继续沿用传统的分工——分析着眼于系统“做什么”,设计解决“怎么做”的问题。而Peter Coad和Edward Yourdon的OOA&D方法则采用了另外一种分工方式——分析阶段只考虑问题域和系统责任,建立一个独立于实现的OOA模型;设计阶段考虑与实现有关的因素,对OOA模型进行调整并补充与实现有关的部分,形成OOD模型。本书的OOD方法主要依据Coad/Yourdon的观点。
Coad/Yourdon的OOD模型包括以下四个部件:人机交互部件、问题域部件、任务管理部件、数据管理部件。与此对应的OOD过程也包括四项活动,设计人机交互部件、设计问题域部件、设计任务管理部件、设计数据管理部件。
通过OOA所得出的问题域精确模型,为设计问题域部件奠定了良好的基础。通常,OOD仅需从实现角度对问题域模型做一些补充和修改,主要是增添、合并或分解类与对象、属性及服务、调整继承关系等。
在OOA过程中,已经对用户界面需求做了初步分析。在OOD过程中,则应该对系统的人机交互部件进行详细设计,以确定人机交互的细节,其中包括指定窗口和报表的形式、设计命令层次等项内容。
主要是识别事件驱动任务,识别时钟驱动任务,识别优先任务,识别关键任务,识别协调任务,审查每个任务并定义每个任务。
提供数据管理系统中存储和检索对象的基本结构,隔离具体的数据管理方案(如普通文件、关系数据库、面向对象数据库等)对其他部分的影响。