军用软件工程
上QQ阅读APP看本书,新人免费读10天
设备和账号都新为新人

2.3 结构化分析方法

结构化分析(Structural Analysis,SA)是由美国Yourdon公司提出的适用于分析典型数据处理系统的,以结构化的方式进行系统定义的分析方法。这个方法通常与L.Constantine 提出的结构化设计(Structural Design,SD)方法衔接起来使用,即所谓的 SA/SD 方法,也可称为面向功能的软件开发方法或面向数据流的软件开发方法。SA/SD 方法首先用结构化分析(SA)对软件进行需求分析,然后用结构化设计(SD)方法进行总体设计,最后是结构化编程(Structural Programming,SP)。结构化分析(SA)方法最初由Douglas Ross提出,由DeMarco推广,由Ward、Mellor及后来的Hatley、Pirbhai扩充,形成了今天的结构化分析方法的框架。结构化分析方法是一种建模技术,它建立的分析模型,如图2.6所示。

图2.6 分析模型的结构

这种分析模型必须达3个主要目标:

(1)描述用户要求。

(2)建立软件设计的基础。

(3)定义软件开发完成时,必须确认的需求集合。

该模型的核心是数据词典,它描述了所有在目标系统中使用的和生成的数据对象。围绕这个核心有 3 种图:实体—关系图(Entity Relationship Diagram,ERD)描述数据对象及数据对象之间的关系;数据流程图(DFD)描述数据在系统中如何被传送或变换,以及描述如何对数据流进行变换的功能(子功能);状态—迁移图(State Transference Diagram,STD)描述系统对外部事件如何响应、如何动作。

因此,ERD用于数据建模,DFD用于功能建模,STD用于行为建模。

2.3.1 数据建模

数据模型包括数据对象、对象属性、对象间关系 3 种互相关联的信息。数据建模要回答与任何数据处理应用相关的一组特定问题,如系统处理哪些主要的数据对象,每个数据对象的组成如何,哪些属性描述了这些对象,这些对象当前位于何处,每个对象与其他对象有哪些关系,对象和变换它们的处理之间有哪些关系。

1.数据对象

数据对象是需要被目标系统所理解的复合信息的表示,所谓复合信息是具有若干不同特征或属性的信息。数据对象可以是外部实体(如显示器)、事物(如报表或显示)、角色(如教师或学生)、行为(如一个电话呼叫)或事件(如单击鼠标左键)、组织单位(如研究生院)、地点(如注册室)、结构(如文件)。

数据对象只封装了数据,没有包含作用于这些数据上的操作。这与面向对象开发方法中的类和对象不同。具有相同特征的数据对象组成的集合仍然称为数据对象,其中的某一个对象称为该数据对象的一个实例。

2.对象属性

属性定义了数据对象的特征。它可用来:

(1)为数据对象的实例命名。

(2)描述这个实例。

(3)建立对另一个数据对象的另一个实例的引用。

如学生数据对象的属性可以有学号、姓名、性别、出生年月、籍贯等。为了唯一地标识数据对象的某个实例,定义数据对象中的一个属性或几个属性为关键码(key),书写为Id,如在学生数据对象中用学号做关键码,它可唯一地标识一个学生数据对象中的实例。

3.对象间关系

各个数据对象的实例之间可以按多种不同的方式相连接。如数据对象“书”与“书店”有关联,可以用图 2.7(a)的符号简单表示。但考虑在待开发软件的上下文环境中“书”与“书店”的关系,可以定义一组对象—关系对来定义相应的连接,如“书店订购书”“书店陈列书”“书店储存书”“书店销售书”“书店返还书”,图2.7(b)给出了这些对象—关系对的图形表示。

图2.7 对象间关系

4.基数和参与性

数据对象、属性和关系是理解问题数据域的基础。但仅有这些信息是不够的,必须提供更进一步的有关数据对象关联的信息。例如,学生“张鹏”选修“软件工程”与“计算机网络”两门课程,学生与课程的实例通过“选修”关联起来。实例的关联有一对一(1∶1)、一对多(1∶m)、多对多(nm) 3种。这种实例的关联称为“基数”,基数表明了重复性。

例如,1名教师带班级中的30名同学,就是1∶m的关系;但也有1名教师带0名同学的情形。所以实例关联有“可选”或“必须”之分,用“〇”表示关系是可选的,用“|”表示关系必须出现 1 次,这表明了“参与性”关系,如图2.8所示。

图2.8 基数与参与性

5.实体—关系图

数据对象及其关系可用实体—关系图(ERD)表示。ERD最初是由Peter Chen为关系数据库提出来的,后来又经过了扩展。ERD的主要目的是表示数据对象及其关系,它包括数据对象、属性、关系等基本成分和各种类型符号。图2.9给出了学生选修课程的ERD及描述学生属性的数据对象表。

图2.9 简单的ERD和数据对象表

数据建模方法用来创建部分分析模型,但它也可以用于设计数据库并支持其他需求分析方法。

实体—关系图的建立步骤如下:

(1)在捕获需求的过程中,要求用户列出应用或业务过程涉及的所有事物。这些事物将来可能会演变为一系列输入/输出数据对象,以及生产和消费信息的外部实体。

(2)一次考虑一个对象。分析人员和用户共同确认这个对象与其他对象之间是否存在连接(在本阶段不命名)。

(3)当存在连接时,分析人员和用户应创建一个或多个对象—关系对。

(4)考察每个对象—关系对的基数和参与性。

(5)迭代执行步骤(2)~(4),直到所有对象—关系对定义完成。在这个过程中发生遗漏是很正常的,每次迭代总会增加新的对象和关系。

(6)定义每个实体的属性。

(7)规范化并复审实体—关系图。

(8)重复执行步骤(1)~(7),直到数据建模完成。

2.3.2 功能建模和数据流

最初,结构化分析方法仅讨论数据流建模,目标系统被表示成如图2.10所示的数据流程图。系统的功能体现在核心的数据变换中,系统的输入源于用方框表示的外部实体,这种输入引发系统的数据变换,产生传递给外部实体的输出。

图2.10 数据流程图

功能建模的思想就是用抽象模型的概念,按照软件内部数据传递、变换的关系,自顶向下逐层分解,直到找到满足功能要求的所有可实现的软件为止。根据DeMarco的论述,功能模型使用了数据流程图来表达系统内数据的运动情况,而数据流的变换则用结构化语言、判定表与判定树来描述。

1.数据流程图

结构化分析的核心部分是数据流程图(Data Flow Diagram,DFD)。数据流程图是一种用来表示信息流程和信息变换过程的图解方法,它把系统看成由数据流联系的各种功能的组合。在需求分析中用它来建立现存或目标系统的数据处理模型,当数据流程图用于软件需求分析时,这些处理或转换,在最终生成的程序中将是若干个程序功能模块。图 2.11 所示为会计账务处理系统的数据流程图。

图2.11 会计账务处理系统的数据流程图

数据流程图包括 4 种基本成分,分别用 4 种基本符号表示,如图 2.12所示。

图2.12 数据流程图的基本符号

从图2.11可以看出数据流有原始凭证、会计报表、记账凭证、账簿等。数据存储包括记账凭证和账簿信息。加工处理有编制记账凭证、登账处理和编制报表。而源点和终点则是往来单位、企业职工和上级部门。

(1)数据流。数据流是描绘数据流程图中各种成分的接口。数据流的方向可以从加工流向加工;从加工流向数据存储;从数据存储流向加工;从源点流向加工或从加工流向终点。数据流的含义如下:

① 数据流是一组成分已知的信息包。信息包中可以有一个或多个已知信息。

② 两个加工间可以有多个数据流,当数据流之间毫无关系,也不是同时流出时,如果强制合成一个数据流,则会使问题更为含糊不清。

③ 数据流应有良好的名字,它不仅作为数据的标识,而且有利于深化对系统的认识,便于进一步了解系统。

④ 同一数据流可以流向不同的加工,不同的加工可以流出相同的流(合并与分解)。

⑤ 流入或流出到存储的数据流不需要命名,因为数据存储的名字已经有足够的信息来表达数据流的意义。

⑥ 数据流不代表控制流。数据流反映了处理的对象,控制流是一种用来选择或影响加工的性质,而不是对它进行加工的对象。

(2)数据加工。数据加工是对数据执行某种操作或变换,是把输入数据变成输出数据流的一种变换。每个加工应有一个名字来概括、代表它的意义。(3)数据存储。数据存储并不等同于一个文件,它可以表示文件、文件的一部分、数据库的元素或记录的一部分等。数据可以存储在磁盘、磁带、存储器和其他介质上。应该认真对数据文件进行命名。在数据流程图中,要注意指向数据文件箭头的方向,读数据的箭头是指向加工处理的;写数据的箭头是指向数据存储的;如果既有读又有写,则是双向箭头。

(4)源点和终点。源点和终点代表系统之外的人、物或组织。它们发出或接收系统的数据,使用起来不严格,其作用是提供系统和外界环境之间关系的注释性说明。一般来说,表示一个系统只要有数据流、加工和文件就够了。但是为了有助于理解,有时可以加上数据流的源点和终点,以此说明数据的来龙去脉,使数据流程图更加清晰。而源与源之间的关系则不予考虑。

画数据流程图的方法是:首先识别出主要输入、输出;然后从输入向输出推进,找出通道上的主要变换。在大多数情况下,原则上是由外向里、自顶向下去模拟问题的处理过程,通过一系列的分解步骤,逐步求精地表达出整个系统功能的内部关系。

画数据流程图的步骤如下:

步骤1 在图的边缘标出系统的输入、输出数据流,从而决定研究的内容和系统的范围。

步骤2 画出数据流程图的内部。将系统的输入、输出用一系列处理连接起来,可以从输入数据流画向输出数据流,或从中间画出。

步骤3 仔细为数据流命名。

步骤4 根据加工的输入、输出内容,为加工命名——“动词+宾语”。

步骤5 不考虑初始化和终点,暂不考虑出错路径等细节,不画控制流和控制信息。

步骤6 反复与检查。思维过程是一种迭代的过程。

应该指出,在需求分析阶段中的数据处理并不一定是一个程序或程序模块,而是反映了系统的功能。如何实现,就要考虑在一定约束条件下软件设计方案的选择和编程问题。另外,它除了代表计算机处理过程,还可以代表人工处理过程,如由专业人员对输入的数据进行正确性检查等。类似地,一个数据的存储也不一定代表一个实际文件,实际数据可以存储在包括人脑在内的任何介质上。

2.分层数据流程图

为了表达数据处理过程的数据加工情况,用一个数据流程图是不够的。稍为复杂的实际问题,在数据流程图上常常出现十几个甚至几十个加工。这样的数据流程图看起来很不清楚,层次结构的数据流程图能很好地解决这一问题。按照系统的层次结构进行逐步分解,并以分层的数据流程图反映这种结构关系,能清楚地表达和理解整个系统。

图2.13为分层数据流程图示例,数据处理S包括3个子系统1、2、3。顶层下面的第 1 层数据流程图为 DFD/L1,第 2 层数据流程图 DFD/L2.1、DFD/L2.2及DFD/L2.3分别是子系统1、2和3的细化。对任何一层数据流程图来说,我们称它的上层图为父图,在它下一层的图则称为子图。

图2.13 分层数据流程图示例

在多层数据流程图中,需要区分顶层流图、底层流图和中间层流图。顶层流图仅包含一个加工,它代表被开发系统。它的输入流是该系统的输入数据,输出流是系统的输出数据。顶层流图的作用在于表明被开发系统的范围,以及它和周围环境的数据交换关系,为逐层分解打下基础。底层流图是指其加工不需要再做分解的数据流程图,它处在最底层,有时也称其加工为原子加工。中间层流图则表示对其上层父图的细化,它的每个加工可能继续细化,形成子图,中间层的多少视系统的复杂程度而定。

画数据流程图的基本步骤概括地说,就是自外向内,自顶向下,逐层细化,完善求精:

(1)首先确定系统的输入和输出,以反映系统与外界环境的接口。

(2)第0层数据流程图将软件系统描述为一个加工,以反映最主要的业务处理流程,它代表系统本身。但它并未明确表达数据加工的要求,需要进一步细化。

(3)从输入端开始,根据系统业务工作流程,画出数据流流经的各加工框,以反映数据的实际处理过程,逐步画到输出端,得到第1层数据流程图。图中的加工分别编号。

(4)细分每个加工框。如果加工框内还有数据流,可将这个加工框再细分成几个子加工框,并在各子加工框之间画出数据流。

(5)一次细化一个加工。数据流程图的细化可以连续进行,直到每个加工只执行一个简单操作为止。就是说,直到每个加工执行一个可以用程序实现的功能为止。

检查和修改数据流程图的原则如下:

(1)数据流程图上所有图形符号只限于前述4种基本图形元素。

(2)顶层数据流程图必须包括前述4种基本元素,缺一不可。

(3)顶层数据流程图上的数据流必须封闭在外部实体之间。

(4)每个加工至少有一个输入数据流和一个输出数据流。

(5)在数据流程图中,需要按层给加工框编号。编号表明该加工处在哪一层,以及上下层父图与子图的对应关系。

(6)规定任何一个数据流子图必须与它上一层的一个加工对应,两者的输入数据流和输出数据流必须一致,此即父图与子图的平衡。

(7)可以在数据流程图中加入物质流,帮助用户理解数据流程图。

(8)图上每个元素都必须有名字。数据流和数据文件的名字应当是名词或名词性短语,表明流动的数据是什么。加工的名字应当是名词+宾语,表明做什么事情。

(9)数据流程图中不可夹带控制流,整个图不反映加工的执行顺序。

(10)初画时可以忽略琐碎的细节,以集中精力于主要数据流。

父图与子图的平衡是分层数据流程图中的重要性质,它保证了数据流程图的一致性,避免分析出错,也便于分析人员阅读和理解。特别地,当某一层数据流程图中的数据存储对象不是父图相应加工的数据接口,而只是本层数据流程图中某些加工之间的数据接口时,这样的数据存储应是局部数据存储。只有当局部数据存储作为某些数据加工之间的数据接口或某个特定加工的输入/输出时,才把它画出来,这样做有利于实现信息隐蔽。

3.加工规格说明

加工规格说明用来说明DFD中数据加工的加工细节。加工规格说明描述了数据加工的输入、实现加工的算法及产生的输出。另外,加工规格说明指明了加工(功能)的约束和限制、与加工相关的性能要求,以及影响加工实现方式的设计约束。必须注意,写加工规格说明的主要目的是要表达“做什么”,而不是“怎么做”。因此它应描述数据加工实现加工的策略而不是实现加工的细节。目前用于写加工规格说明的工具有程序设计语言、判定表和判定树。

1)程序设计语言

程序设计语言(Program Design Language,PDL)也称为结构化语言,它是一种介于自然语言和形式化语言之间的半形式化语言。它是在自然语言基础上加了一些限制而得到的语言,它使用有限的词汇和有限的语句来描述加工逻辑。一般来说,对于顺序执行和循环执行的动作,用结构化语言描述;对于存在多个条件复杂组合的判断问题,用判定表和判定树。

结构化语言的结构分为外层和内层,外层用来描述语言正文。它将语言正文用基本控制结构进行分割,基本控制结构包括简单陈述句结构、判定结构(IF_THEN_ELSE_ENDIF或CASE_OF_ENDCASE)和重复结构(WHILE_DO或REPEAT_UNTIL)3种。

内层一般采用祈使语句的自然语言短语,使用数据词典中定义的名字和有限的自定义词。其动词含义要具体,尽量不用形容词和副词来修饰,还可以使用一些简单的算术运算和逻辑运算符号。

此外在书写时,必须按层次横向向右移行,续行也同样向右移行,对齐。下面是某商店业务处理系统中“检查发货单”的例子。

2)判定表(Decision Table)

在某些问题中,数据流程图中某个加工的一组动作依赖于多个逻辑条件的取值,就是说完成这一加工的一组动作是由于某一组条件取值的组合引发的。这时使用判定表来描述比较合适,它可以清楚地表示复杂的条件组合与应做动作之间的对应关系。

下面以检查发货单为例,说明判定表的构成,如图2.14所示。

图2.14 检查发货单的判定表图

判定表由4个部分组成,如图2.15所示。双线分割开的4个部分是条件茬、动作茬、动作项和条件项。

图2.15 判定表的结构

(1)条件茬。条件茬部分列出了各种可能的条件。除去某些问题中对各条件的先后次序有特定要求外,通常判定表中条件茬所列条件的先后次序无关紧要。条件项是针对各种条件给出的多组条件取值的组合。

(2)动作茬。动作茬列出了可能采取的动作。这些动作的排列顺序并没有什么约束,但为便于阅读也可令其按适当的顺序排列。

(3)动作项和条件项。动作项和条件项紧密相关,它指出了在条件项各组取值的组合情况下应采取的动作。

任一条件取值组合及其要执行的相应动作称为规则,它在判定表中是纵向贯穿条件项和动作项的一列。显然,判定表中列出了多少个条件取值的组合,也就有多少条规则,即条件项与动作项有多少列。

3)判定树(Decision Tree)

判定树也是用来表达加工逻辑的一种工具,有时候它比判定表更直观。用它来描述加工,很容易为用户接受。下面把前面的检查发货单的例子用判定树表示,如图2.16所示。

图2.16 判定树

在表达一个基本加工逻辑时,结构化语言、判定表和判定树常常被交叉使用,互相补充。这3种手段各有优缺点。从易学易懂的角度看,判定树最易学,易懂;结构化语言次之;判定表较难懂。判定表最易进行逻辑验证,因它考虑了全部可能的情况,逻辑清晰,能够澄清疑问;结构化语言次之;判定树较难验证。判定树的表达是直观的图形表示,一目了然,易于同用户讨论;结构化语言次之;判定表则不够直观。作为文档,结构化语言较好表达;判定表次之;判定树居后。从可修改的角度看,结构化语言较易修改;判定树次之;判定表较难修改。

没有一种统一的方法来构造判定树,也不可能有统一的方法,因为它是以用结构化语言,甚至是自然语言写成的叙述文作为构造树的原始依据的,但还是可以从中找出一些规律。首先,应从文字资料中分清哪些是判定条件,哪些是判定做出的结论。例如,在上面的例子中,判定条件是“金额>$500,欠款≤60 天的发货单”,要判定的结论是“发出批准书和发货单”。然后,从资料叙述中的一些连接词(如除非、然而、但、并且、和、或……)中,找出判定条件的从属关系、并列关系、选择关系等。

通过对以上情况的分析,可知对于不太复杂的判定条件,或者使用判定表有困难时,使用判定树较好。而在一个加工逻辑中,如同时存在顺序、判断和循环时,使用结构化语言较好。而对于复杂的判定,组合条件较多,则使用判定表较好。

总之,加工逻辑说明是结构化分析方法的组成部分,对每个加工都要加以说明。使用的手段,应当以结构化语言为主,对存在判断问题的加工逻辑,可辅之以判定表和判定树。

2.3.3 行为建模

行为建模给出需求分析方法的所有操作原则,但只有结构化分析方法的扩充版本才提供这种建模的符号。

1.状态—迁移图

利用如图2.17所示的状态—迁移图(STD)或状态—迁移表来描述系统或对象的状态,以及导致系统或对象的状态改变的事件,从而描述系统的行为。

每个状态代表系统或对象的一种行为模式。状态—迁移图指明系统的状态如何响应外部的信号(事件)进行推移。在状态—迁移图中,用圆圈“○”表示可得到的系统状态,用箭头“→”表示从一种状态向另一种状态迁移。箭头上要写明导致迁移的信号或事件的名字。如图 2.17(a)所示,系统中可取得的状态=S1、S2、S3,事件=t1、t2、t3、t4。事件t1将引起系统状态S1向状态S3迁移,事件t2将引起系统状态S3向状态S2迁移,等等。图2.17(b)是与图2.17(a)等价的状态—迁移表。

图2.17 状态—迁移图及与其等价的状态—迁移表例

另外,状态—迁移图指明了作为特定事件的结果(状态)。在状态中包含可能执行的行为(活动或加工)。

如果系统比较复杂,可以将状态—迁移图分层表示。例如,在确定了图2.18所示的大状态S1、S2、S3之后,接下来就可把状态S1、S2、S3细化,图2.18对状态S1进行了细化。此外,在状态—迁移图中,由一个状态和一个事件所决定的下一个状态可能会有多个。实际会迁移到哪个是由更详细的内部状态和更详细的事件信息来决定的。此时,可采用状态—迁移图的一种变形(见图2.19),使用加进判断框和处理框的记法。

图2.18 状态—迁移图

图2.19 状态—迁移图的变形

2.Petri网

Petri网(Petri Net Graph,PNG)适用于描述相互独立、协同操作的处理系统,即并发执行的处理系统。在软件需求分析与设计阶段都可以使用。

Petri网是一种有向图,它有两种结点:“○”表示系统的状态,“—”或“┃”表示系统中的事件。图中的有向边表示对事件的输入,或从事件输出;“”表示对事件的输入;“”表示事件的结果,即从事件的输出。

图 2.20 用 Petri 网描述了在一个多任务系统中的两个进程 PR1 和 PR2使用一个公共资源R时,利用原语LOCK(对资源加锁)和UNLOCK(对资源解锁)控制R的使用,保证进程间同步的例子。

图2.20 进程同步机制的PNG

图2.20中每个进程是一个数据对象,它有3个状态:等待资源(p1或p4),占用资源执行的处理(p2或p5),不占用资源执行的处理(p3或p6);另外系统有一个资源空闲(p7)状态。有的状态中有一个黑点“”,称为标记或令牌,它表明系统或对象当前正处于此状态。当作为一个事件输入的所有状态都得到或保有令牌时,才能引起该事件激发,使得系统和对象的状态向前推移,完成系统和对象的某些行为。

3.控制规格说明

控制规格说明从两个方面给出系统的行为,一是状态—迁移图(STD),它是行为的顺序规格说明;二是加工激活表(PAT),它是行为的组合规格说明,表明当事件激发时,数据流程图中哪些加工要被激活。

加工激活表是在加工的环境中,而不是在状态的环境中。它包含状态—迁移图中的信息,表明当某个事件发生时,控制流图中的哪些加工要被激活。

控制规格说明仅描述了系统的行为,不提供被激活加工内部工作的细节。