2.4 结构化分析方法
结构化分析(Structured Analysis, SA)是20世纪70年代中期由E.Yourdon等人倡导的一种面向数据流的分析方法。结构化分析是一个简单实用、使用很广的方法。它适用于分析大型的数据处理系统,特别是企事业管理方面的系统。这个方法通常与设计阶段的结构化设计(SD方法)衔接起来使用。
结构化分析模型的组成结构如图2-16所示。由图可见,模型的核心是DD,它是系统所涉及的各种数据对象的总和。从DD出发可构建3种图。
图2-16 结构化分析模型的组成结构
● E-R(Entity-Relation Diagram,实体-关系图),用于描述数据对象间的关系,它代表软件的数据模型,在E-R图中出现的每个数据对象的属性均可用数据对象说明来描述;
● DFD,其主要作用是指明系统中数据是如何流动和变换的,以及描述使数据流进行变换的功能,在DFD图中出现的每个功能的描述则写在加工说明(PSPEC)中,它们一起构成软件的功能模型;
● STD(Status Transfer Diagram,状态-变迁图),用于指明系统在外部事件的作用下将会如何动作,表明了系统的各种状态以及各种状态间的变迁,从而构成行为模型的基础,关于软件控制方面的附加信息则包含在控制说明(CSPEC)中。
早期的结构化分析模型仅包括DD、DFD、PSPEC等3个组成部分,主要用于描述软件的数据模型(用DD)与功能模型(用DFD和PSPEC)。随着社会信息化的迅速发展,许多应用系统包括了较复杂的数据信息。因而在数据建模时,有人将原用于关系数据库设计的E-R图改用于结构化分析,以便描述包含较为复杂数据对象的信息模型。另一方面,随着计算机实时系统应用的不断扩大,人们在分析建模中发现,有些数据加工并非是由数据来触发,而是由实时发生的事件来触发/控制的,无法用传统的DFD来表示。因而在20世纪80年代中期,以Ward和Hatley等为代表的学者又在功能模型之外扩充了行为模型,推荐用CFD(Control Flow Diagram,控制流图)、CSPEC和STD等工具进行描述。如今,结构化分析模型已可同时覆盖信息模型、功能模型和行为模型等3种模型,其适用的软件范围也更加大了。
2.4.1 结构化分析的基本思想
通过调查研究,系统分析员在比较全面地获取用户要求以后,一个重要的任务是对用户需求分析进行描述,其主要目的是对用户各种要求进行分析与综合,排除其中可能存在的不一致性和二义性,并以某种规范化的形式准确、完整地描述出来。
SA方法以数据流分析作为需求分析的出发点,任何信息处理过程均看成是将输入数据变换成所要求的输出信息的装置。而分析人员面对一个复杂的问题时,SA方法是基于问题分解与抽象的观点,用抽象模型的概念,按照软件内部的数据传递关系,采用自顶向下、逐层分解技术,直至找到满足功能需求的可实现软件单元为止。SA方法采用“分解”的方式来理解一个复杂的系统,“分解”需要有描述的手段,数据流图就是作为描述“分解”的手段引进的。
具体做法是首先将整个系统看成一个加工信息处理装置,是一个黑盒子,标识出系统边界和所有输入输出数据流。然后自顶向下,对加工内部进行细化,逐层分解,将复杂功能分解为若干简单功能的有机组合,绘制数据流图。
2.4.2 描述方式
由于目前还没有既能精确地描述大型系统的用户要求,又是简明易懂的形式语言,因此SA方法采用了介于形式语言和自然语言之间的描述方式。它虽然不如形式语言精确,但是简明易懂,所表达的意义也比较明确:
● 用一套分层的数据流图;
● 一本数据字典;
● 一组加工说明;
● 补充材料。
这套文档中,“数据流图”描述系统的分解,即描述系统由哪些部分组成、各部分之间有什么联系等;“数据字典”描述系统中的每一个数据;“加工说明”则详细描述系统中的每一个加工。上述资料再加上视系统而定的各种补充材料可明确而完整地描述一个系统的功能。
SA方法在描述方式上的特点是尽量采用图形表示,因为图形比较形象、直观和易于理解,一张图的表达效果可能比几千字的叙述还要好。
2.4.3 结构化分析步骤
1.由顶向下逐层分解
软件工程技术中,控制复杂性的两个基本手段是分解和抽象。对于一个复杂的问题,由于人的理解力、记忆力均有限,所以不可能触及问题的所有方面以及全部的细节。为了将复杂性降低到人可以掌握的程度,可以把大问题分成若干个小问题,然后分别解决,这就是“分解”;分解也可以分层进行,即先考虑问题最本质的属性,暂把细节略去,以后再逐层添加细节,直至涉及最详细的内容。
对于一个复杂的系统,如何理解和表达它的功能呢?SA方法使用了“自顶向下逐层分解”的方式,图2-17中系统X很复杂,为了理解它,可以将它分解成1、2、3、4几个子系统;如果子系统1和2仍然很复杂,可以将它们再分解成1.1、1.2等,并为每个细节写下加工说明,再将所有这些“加工说明”组织起来,就获得了整个系统X的系统说明书。
图2-17 系统X的逐层分解
“逐层分解”体现了分解和抽象的原则,它使人们不至于一下子陷入细节,而是有控制地逐步地了解更多细节,这是有助于理解问题的。
图2-17中的顶层抽象地描述了整个系统,低层具体地画出了系统的每一个细节,而中间层则是从抽象到具体的逐步过渡。按照这样的方式,无论系统多么复杂,分析工作都可以有计划、有步骤地进行,系统规模再大,分析工作的复杂程度不会随之增大,而只是多分解几层而已,所以SA方法有效地控制了复杂性。
2.由外向内画数据流图
最初的数据流图应是描述当前的实际情况,即当前存在的人工数据处理情况,为此分析员应将他在一个企业组织中看到、听到的事实如实画出来。用户目前使用的单据、表格、卡片、清单等资料就是“数据流”或“文件”。用户目前在做的工作就是“加工”,它们的名字就是用户习惯使用的名字。总之,在刚开始时只是将现实情况反映出来,而不是急于去想象未来的计算机系统是怎样的。
在画数据流图时,首先应画出系统的输入数据流和输出数据流,也就是先决定系统的范围,然后再考虑系统的内部,同样,对每一个加工来说也是先画出它们的输入、输出,再考虑这个加工的内部。
(1)建立顶层数据流图。最初,我们把系统视为一个整体,顶层流图只包含一个加工,用以标识被开发的系统,看这个整体与外界的联系,分析有哪些内容是要通过外界获取的,就是系统的输入;有哪些是要向外界提供服务的,就是系统的输出,画系统的输入/输出数据;数据的源点和终点对应着外部实体,表明系统输入数据的来源和输出数据的去向。学籍档案管理系统的顶层数据流图如图2-18所示。
图2-18 成绩管理系统的顶层数据流图
学籍档案管理系统的顶层数据流图描述了学籍档案管理系统与外界的简单关系。
(2)数据流图的分层细化。数据流图主要是用于描述系统内部的处理过程。有些内部处理过程比较简单,有些则相当复杂,为了能够清楚表明系统加工的详细过程,需要对系统加工的功能细化,即对顶层数据流图进行分解。
按照系统的功能,对顶层数据流图进行分解,生成第一层数据流图。如例子中的成绩管理系统可划分为成绩登录、成绩统计、成绩查询和成绩发布四个加工。对划分得到的加工应进行编号。如图2-19中成绩登录的编号为1,成绩统计的编号为2,依此类推,加工之间的数据流也应在数据流图中标明,如学生成绩从“成绩统计”加工流向“成绩发布”加工。此外,在标出数据流和划分加工的同时,还要在图中画出设计的数据存储。如果加工的内部还有数据流,则对此加工在下层图中继续分解,直到每一个加工足够简单,不能分解为止。不再分解的加工称为基本加工。图2-20就是对“成绩查询”加工进行分解得到的第二层数据流图。
图2-19 成绩管理系统第一层数据流图
图2-20 第二层成绩查询数据流图
3.建立数据流图的原则
在软件的系统分析之前,要制定一个系统的标准,其内容之一就是画数据流图的规范。画数据流图时要注意以下几点:
(1)注意父图与子图的平衡。对数据流图中每个加工进行细化生成的下层数据流图,称为其上层图的子图,子图的输入、输出数据流同父图对应加工的输入、输出数据流必须一致,即父图与子图的平衡。以图2-21为例,图中联系到外部项的数据共有六个,即两个输入数据流——单科成绩和成绩查询,四个输出数据流——成绩、成绩统计信息、成绩通知单和补考通知,这和图2-19只差一个输出数据流——补考通知,为什么?
图2-21 父子图不平衡
这看起来并不平衡,因为补考通知是一个枝节性的数据流,通常这类信息可以推迟到低层考虑,在上层可不必画出,所以,这两张图仍然是平衡的。除了类似这样的例外情况(包括:出错处理信息也需要在低层添加进去)外,如果发现了父图和子图的数据不平衡,都应检查在分解中有无出错。
图2-21中的父图和子图是不平衡的,因为子图中没有输入数据流与父图中加工3的输入流M相对应。另外,子图的输出数据流S在父图中也没有出现。
图2-22中的父图和子图平衡吗?从图上看,子图与父图中相应加工并不具有相同的输入和输出,但是如果从字典中查出:父图中称为“订货单”的数据流是由“客户”、“账号”和“数量”三部分数据组成的,那么就可得出结论:这两张图是平衡的。
图2-22 父图与子图
如果子图的输入输出数据流比父图中相应加工的输入输出表达得更详细,实际上就是对“加工”和“数据”同时进行分解,由顶向下同时对加工和数据流做逐层分解是很自然的方式,所以是经常使用的,在这种情况下,检查“平衡”就必须借助字典来进行。
父图和子图必须平衡,这是分层数据流图的重要性质,平衡的分层图是可读、可理解的;反之,如果父图和子图不平衡,这套数据流图就无法理解。
(2)局部文件。图2-19和图2-20所示的两张数据流图是平衡的,但是子图中的课程和成绩档案为什么在父图中没有画出呢?这是因为这两个文件是完全局部于图2-18所示的加工之间的文件,它并不是父图中各个加工之间的交界面,根据“抽象”原则,在画父图时,只需画出加工和加工之间的联系,而不必画出各个加工内部的细节,所以在父图中不必画出课程和成绩档案这两个文件,这样做的两个好处是:减少图形的复杂度和保持了画面整洁。
(3)数据流的分解速度应保持适中。通常一个加工每次可分解为2~4个子加工,最多不要超过7个,因为过快的分解会增加用户对系统模型的理解难度。
(4)命名。数据流图中各构成元素的名称必须具有明确的含义且能够代表对应元素的内容或功能。命名时不能使用抽象含义的名字,如“数据”、“信息”等。加工名的命名也要反映其处理的功能,不能使用“处理”、“操作”等这些笼统的词。
(5)每个加工至少应有一个输入数据流和一个输出数据流,反映出此加工数据的来源与加工结果。
(6)加工编号。在数据流图中,应按照层次给每个加工编号,用于表明该加工所处的层次及上、下层的父图与子图的关系。编号的规则为:顶层加工不用编号;第二层加工的编号为1, 2, …, n;第三层加工的编号为1.1, 1.2, …, 2.1, 2.2, …, n.1, n.2, …,依此类推,如编号为1.2表明该加工处于第三层数据流图中,序号为2,该图是对上层数据流图中编号为1的加工进行细化得到的子图。
可从以下几个角度来检查数据流图的正确性:
● 数据守恒;
● 文件的使用;
● 父图和子图的平衡。
4.数据字典描述
(1)数据流条目。如下所示。
(2)数据文件。与数据流条目一样,对存储数据的定义使用数据文件条目。数据文件条目主要内容有:数据文件名称、主键编号、辅键、存储组织、记录组成、简要说明等,如下所示。
(3)数据项条目。数据项是数据的基本单位。通常,一个数据流或数据文件由若干个数据项组成。数据字典的数据条目中应包含的主要内容有:数据项名称、数据项别名、类型、长度、属于数据流、取值范围及含义等,如下所示。
字典一般可用一叠卡片来构造,如果用户的要求有变化,则字典就要做相应的修改。因为字典的容量一般比较庞大,人工维护一本字典很花时间,也很单调乏味,可以用计算机代替人来完成这项机械而又烦琐的工作,负责这种工作的程序系统称为“字典管理程序”,或简称为“字典”。
5.加工说明
【例2-3】 用结构化语言描述图2-19所示成绩管理系统数据流图中的“成绩登录”加工。
接收单科成绩 从课程(D1)查出课程的学分 IF普通考试成绩 DO WHILE对于成绩单中每个学生 IF学生成绩大于合格成绩 记录学生的成绩,学分 ELSE 记录学生的成绩,学分为0 ENDIF ENDDO ELSE DO WHILE对于成绩单中每个学生 IF学生的补考成绩大于合格成绩 记录学生的补考成绩,学分 ELSE 记录学生的补考成绩,学分为0 ENDDO ENDIF
【例2-4】 用结构化语言描述图2-19所示成绩管理系统数据流图中的“成绩统计”加工
接收成绩档案(D2)的数据 DO WHILE对于每个学生 计算该生本学年所学课程的总分、平均分 ENDDO 以班级为基准,按总分从高到低排名次 IF向“成绩发布”加工传数据 按名次顺序将学生各课程成绩、总分、平均分输出 ELSE统计各成绩等级人数,计算各成绩等级人数所占总人数的百分比 //判断获得奖学金的学生 IF所有考试考查课成绩均90 分以上或“优秀” 获得一等奖 ELSE IF考试考查课成绩均85 分或“良好”以上 获得二等奖 ELSE IF考试考查课成绩均75 分或“中等”以上 获得三等奖 ENDIF 向学生科输出统计数据 ENDIF
获得奖学金学生的判断逻辑:如果所有考试考查课成绩均90分以上或“优秀”,则可以获得一等奖;如果考试考查课成绩均85分或“良好”以上,则可以获得二等奖;如果考试考查课成绩均75分或“中等”以上,则可以获得三等奖。
下面以描述成绩管理系统的“成绩统计”加工中获得奖学金学生的判断逻辑为例,说明判定表的写法,如图2-23所示。
图2-23 判定表