人类认识世界总是循序渐进的过程,软件工程也一样,从最开始的单兵作战,再到软件作坊,直到如今的大规模软件开发,软件工程从业者不断总结实践中存在的问题以及解决途径,逐渐形成了一系列的软件工程方法,而所有这些方法中,最为经典的当属结构化和面向对象的方法。本文将在认识两种方法的基础上探讨如何在软件工程过程中将这两种方法结合起来。
1 结构化方法
1.1 结构化方法的基本思想
面对复杂的问题,我们先要想办法让它变得简单。结构化方法的基本思想就是通过自顶向下、逐步求精、模块化的方法来让让复杂的软件开发过程变得简单。
- 自顶向下、逐步求精就是指把一个复杂的问题划分成若干小问题,然后再分别解决,将问题的复杂性降低到人可以掌握的程度。即将复杂的系统分解成若干个人们易于理解和分析的子系统。在分解过程中,被分解的上层就是下层的抽象,下层为上层的具体细节,即最高层的问题最抽象,而底层的则较为具体。
- 模块化就是把程序划分成若干个模块,每个模块完成一个子功能,将多个模块组织起来实现整个软件系统的功能。模块化设计方法强调清楚地定义每个模块的功能和它们的输入/输出参数,而模块的实现细节隐藏在模块中,与 其他模块之间的关系是调用关系,因此,模块化程序易于调试和修改。
1.2 结构化软件工程过程
将上述思想融入到软件工程的各个过程,便是结构化软件工程过程。包括:
- 结构化分析:应用结构化方法进行软件需求分析时,是基于数据流的。即通过数据流图的自顶向下逐层分解来建立目标系统的功能模型,通过数据字典和E-R图来构建数据模型,通过流程图和状态转换图来构建行为模型,最后形成该阶段的里程碑文档:《需求规格说明书》,为下一步的软件设计提供依据。
- 结构化设计:在结构化分析的基础上,采用面向数据流的设计方法,以数据流图为基础得到软件的模块结构,应用流程图、PDL语言、判定表或判定树设计代码逻辑,最后形成该阶段的里程碑文档:《软件设计说明书》,文档中还需要对各模块内部及模块间的接口(包括界面设计)做出说明,为软件实现阶段的工作提供依据。
- 结构化程序设计:就是采用一种面向过程的程序设计语言,实现上述设计的系统。
1.3 结构化软件工程工具

图1 结构化方法建模过程
如图1所示,结构化方法应用一系列工具来对系统进行建模。下面,本文将结合一个案例来说明这些工具的适用场景。
案例描述:某学院拟开发一个教学档案管理系统(以下简称“系统”),具有如下功能。
(1)登录。管理员、普通教师和系主任可以利用系统预设的账号、密码登录系统,完成相应的功能。
(2)部门管理。管理员登录系统后,可维护学院的部门信息,包括部门编号、部门名称、部门类别、办公室地址等。
(3)教师管理。管理员登录系统后,可维护教师信息,包括工号、姓名、性别、所属部门、职务(普通教师或系主任)等。
(4)课程类型管理:管理员登录系统后,可维护课程类型信息,包括类型编号、类型名称(如“理论课”、“实践课”等)等。
(5)档案类型管理。管理员录系统后,可维护档案类型信息,包括档案类型编号、档案类型名称、所属课程类型、档案模板、归档要求等。
(6)授课管理。系主任登录系统后,可为所在部门的教师安排每学期教授的课程信息,包括课程编号、课程名称、课程类型、学期、授课班级、开始时间、结束时间、学时、授课地点等。
(7)档案管理。普通教师登录系统后,可选择上传自己所教授课程的档案, 每门课有多个档案,每个档案的信息包括档案编号、档案文件、档案说明等, 上传后可选择临时保存以便于下次接着上传或修改已上传的档案,如果确认全部上传完成,则选择提交系主任审核;系主任登录系统后,可对教师上传的档案进行审核,如果没有问题,则选择审核通过;否则选择驳回。管理员登录系统后,可按部门或学期查询所有课程的档案上传情况。
1.3.1 数据流图
数据流图(Data Flow Diagram,DFD)用于刻画业务处理过程中需要进行的操作以及外部实体与系统之间、系统内部操作之间的信息传递过程。如图2所示,数据流图包含4种要素,每种要素在Yourdon表示法和Gane表示法中的表示形式略有不同。

图2 数据流图的要素
Yourdon表示法和Gane表示法是两种用于系统分析和设计的图形表示方法。前者由美国计算机顾问、作家和软件工程师Edward Yourdon于1970年代开发,后者由英国工程师J. Gane和C. Sarson于1979年开发。本文主要使用Gane表示法来绘制数据流图。
绘制数据流图的过程就是结构化的系统建模过程,基本步骤包括:
- 确定外部实体,画出顶层数据流图。
- 对顶层数据流图的加工进行分解:从数据源点出发,按照系统的逻辑需要,逐步画出一系列逻辑加工,直至数据终点。自顶向下,对每个加工进行内部分解,画出分层数据流图。
- 对数据流图进一步求精。
(1)顶层数据流图:又称0层数据流图或环境图,其作用是确定系统在其环境中的位置,通过确定系统的输人和输出及其与外部实体的关系来确定系统的边界。

图3 教学档案管理系统顶层数据流图
如图3所示,数据流图包含如下几个要素:
- 外部实体:代表与系统进行交互的人员、组织或其他系统。外部实体用矩形表示。图1中管理员、普通教师、系主任均属外部实体。
注意:需求分析时识别的外部实体,除了管理员之外,其他都是现实世界中实际存在的角色,不要用“用户”这样的名称替代。
- 数据变换:也称加工,代表系统包含的操作。对于顶层数据流图来说,只有一个加工,那就是我们要开发的系统。加工用圆角矩形来表示。
- 数据存储:代表系统数据存放的地方。数据存储用带编号的右侧开口矩形表示。
- 数据流:代表外部实体与加工之间、加工与加工之间、加工与数据存储之间传递的信息。数据流使用带箭头的线表示,箭头表示信息传递的方向。如图1中,管理员操作系统时需要输入账户、密码完成登录,所以管理员和系统之间就有一个名为“账户、密码”的数据流。由于数据流表示的是数据信息,所以其名称应该是一个名词,而非动词。
(2)数据流图的分解
为了更加详细的了解系统的内部流程,需要对数据流图中的加工进行逐层分解,分解时要满足下图所示的一致性原则:

图4 数据流图分解的一致性原则
数据流图在分解过程中,下层对上层的加工进行分解,分解后的输入和输出数据流与上层 保持一致。如图4所示,底层将中间层的加工S1分解为3个子加工S1.1、S1.2、S1.3,分解后作为整体,输入的数据流为1条(图中用红色表示),即从外部实体F1到S1.1,输出的数据流有3条(图中用蓝色表示),即1条输出到外部实体F1,另外2条分别由S1.1到S2.1和由S1.3到S2.2,这与中间层数据流图中S1对应的数据流是一致的。
图5给出了分解后的结果:

图5 分解后的数据流图
注:绘制数据流图的过程是一个逐步求精的过程,除了图4所示的一致性原则外,还要遵守以下原则:
- 顶层DFD应该将软件描述为一个“泡泡”。
- 主要的输入和输出应该仔细标记。
- 通过分离在下层表示的候选处理过程、数据对象和数据存储,开始求精过程。
- 应使用有意义的名称标记所有的箭头和泡泡。
- 当从一层转移到另一层时要保持信息流的连续性。
- 一次精化一个泡泡。
- 数据流图不同于流程图,它注重的是数据在系统中的流动,在加工间的多个数据流之间不需考虑前后次序问题,加工只描述“做什么”,不考虑“怎么做”和执行顺序的问题。
- 要避免出现没有输出的数据流或有输入没输出的加工。
- 数据流图的分解应根据问题的逻辑特性进行,不能硬性分解:每个加工分解为子加工后,子图中的子加工数不要太多;上层比较抽象可分解快些,下层分解慢些,易于理解。
- 分解到达底层,数据流图一般应满足两个条件:加工能用几句或十几句话就可清楚地描述其含义;一个加工基本上只有一个输入流和一个输出流。
以上准则或注意事项只是参考,在实际应用时不要生搬硬套,以符合逻辑、自然、清晰为宜。
1.3.2 数据字典
数据字典是结构化分析方法的核心,它用于描述分析过程中产生的所有对象及其要素。由于经常用于描述数据流图各主要元素,所以笔者给它起了个比较好记的名字,叫做“DFD伴侣”。还以教学档案管理系统为例,我们前面通过数据流图的形式明确了外部实体、主要的加工及数据流,但仅仅通过图的方式还不能明确每个元素的细节,所以我们需要通过数据字典对其进行详细说明。
(1)数据字典的内容
数据字典主要描述数据流图中的四类元素,即数据源点/终点、数据存储、处理和数据流。
- 对每个数据元素,都需要描述其一般信息,如数据元素的名字、别名、用途等。
- 定义数据元素的类型、长度、结构组成等。
- 描述数据元素的使用特点,如取值范围、使用频率、使用方式等。
- 描述数据元素的控制信息,如数据来源、用户、使用它的程序、改变权、使用权等。
- 描述数据元素的分组信息,如父结构、从属结构、物理位置等。
(2)数据字典的定义方法
以数据流的数据字典为例,其定义方式主要有两种,一种是如图6所示,该方式用于说明数据流由哪些数据项组成以及针对每个数据项给出具体的定义。数据项的组成关系通常包括顺序、选择、重复和可选四种。
- 顺序关系,是指一个元素由多个元素连接而成,用+号表示。
- 选择关系,是指一个元素由多个中选一个而成。用[1号表示,如[a|bc]表示从 a、b、c中选择一个。
- 重复关系,是指一个元素由另一个简单元素重复零次或多次得到。用{}号表示,如a{char}b,表示由若干个字符组成,其中a表示个数上限,b表示个数下限。
- 可选关系,表示可有可无。用()号表示。如(char),表示char可有可无。
图6 数据字典
另一种方式,是采用表格的方式,对数据流包含的各个数据项加以说明。表1给出了图6所示“学生信息”对应的数据字典。
| 序号 | 数据流名称 | 数据项名称 | 数据类型 | 描述 |
| 1 | 学生信息 | 学号 | 12{字符}12 | 学生唯一标识 |
| 姓名 | 4{字符} 20 | 学生的真实姓名 | ||
| 密码 | 6{字符}20 | 学生登录密码 | ||
| 家庭住址 | 10{字符}100 | 学生家庭住址 | ||
| 联系电话 | 6{字符}20 | 联系电话 | ||
| 邮箱 | 6{字符}30 | 邮箱 | ||
| ...... | ...... | ...... | ...... | ...... |
这里笔者推荐的一种做法是把两种方式结合起来使用,即用第一种方式给出数据流的简要描述和数据项组成,然后用第二种方式通过表格给出数据项的具体说明。 表2给出了数据字典中常用的符号。
| 符号 | 含义 | 示例 |
| = | 被定义为 | X=a+b |
| + | 与 | X-a+b表示X由a和b组成 |
| […|...] | 或 | X=[a|b]表示X由a或b组成 |
| m{...}n或 | 重复 | X=2{a}6或 |
| {...} | 重复 | X={a}表示X由0个或多个a组成 |
| (...) | 可选 | X=(a)表示a在X中可能出现,也可能不出现 |
| “...” | 基本数据元素 | X=“a”表示X是取值为字符a的数据元素 |
| .. | 连接符 | X=1..9表示X可取1到9中的任意一个值 |
当然,不单是数据流要有数据字典说明,数据流图的其他元素也要有对应的数据字典,下面以图5分解后的数据流图为例,分别加以说明。
1)数据存储描述={数据存储名,说明,编号,流入的数据流,流出的数据流,组成:{数据结构},数据量,存取方式},示例如下:
- 名称:档案信息
- 说明:用于存储档案信息
- 编号:D6
- 输入的数据流:档案信息
- 输出的数据流:档案信息
- 组成:档案编号+档案文件+档案说明+课程编号
- 数据量:1000条/学期
- 存取方式:逐条录入;随机检索。
2)处理过程(加工)描述={处理过程名,说明,输入:{数据流},输出:{数据流},处理:{简要说明}},示例如下:
- 名称:档案审核
- 说明:查看待审核档案,根据档案上传要求,给出审核结果(通过或不通过)
- 输入:档案信息+审核信息
- 输出:审核信息
- 数据量:1000条/学期
- 处理:系主任登录后查看待审核档案;录入审核结果;提交审核结果。
1.3.3 实体-关系图
实体-关系图,用于分析系统的数据需求,它由实体(Entity)和实体间关系(Relationship)两部分组成,因此简称E-R图。
所谓实体,是指系统操作过程中涉及的数据对象,如教师、档案等。
关系是指实体之间的数据关系,如图7所示,在档案管理系统中,我们不但要单独记录每个教师和档案的信息,还需要记录档案是哪位教师上传的档案,因此档案和教师之间还会存在“上传”这样一种关系,而且还需识别实体之间的对应关系是1对1(记作:1-1)、1对多(记作:1-n)还是多对多(记作:n-m),很明显,1名教师可以上传多个档案,因此他们之间是1对多的关系。

图7 E-R图
在E-R图中我们还需要标记实体及关系的属性,也就是实体及关系包含的数据项有哪些,如果E-R图中包含的实体较多,我们可以在E-R图中只标识关系的属性,对于实体,则单独绘制实体属性图(如图8所示)。

图8 实体属性图
注意:1)实体-属性图中有一类属性是用于唯一标识该实体的,我们称其为主键或关键字,需要用下划线标识,如图8中的工号,就是用来唯一识别教师这个实体的。 2)实体关系图中的关系是指两个实体间的数据关系而非操作关系,这样的关系一旦出现在E-R图中,就意味着将来在设计数据库时就要有对应的数据表或字段来记录这样的关系。3)不同的人由于对数据关系的理解不同,所以绘制的E-R图也不尽相同,因此,E-R图不具有唯一性,只要格式规范、能够清晰的表达数据需求即可。
1.3.3 状态转换图
状态转换图(State Transform Diagram,STD)用于表示行为模型,即系统对外部事件如何响应和动作。通过描述系统的状态和引起系统状态转换的事件,来表示系统的行为,指出作为特定事件的结果将执行哪些动作(例如,处理数据等)。
状态转换图可以用来描述各种系统,包括软件系统、硬件系统、通信协议等等。如图9所示,每一个节点代表一个状态,其中双圈是终结状态。状态节点中的状态变量和活动表为可选项,前者用于指定记录状态信息的变量,后者给出该状态下可能的内部活动列表。状态转换通常是由事件触发的,在这种情况下应在表示状态转换的箭头线上标出触发转换的事件表达式,否则表示在源状态的内部活动执行完之后自动触发转换。在一张状态转换图中只能有一个初态,而终态则可以没有,也可以有多个。

图9 状态转换图
状态转换图可以帮助我们理解系统的行为模式,识别系统的状态和转换条件,并帮助进行系统设计和测试。它能够清晰地展示系统的状态及其之间的转换关系,有助于发现系统中可能存在的问题和异常情况。图10给出了档案管理系统中归档过程的状态转换图。

图10 归档处理状态转换图
注:1)状态转换图描述的是系统状态和事件,事件引发系统在状态间的转换,而不是描述系统中数据的流动。2)并不是所有系统都需要画状态转换图,这种模型尤其适合用来描述实时系统,因为这类系统多是由外部环境的激励而驱动的。
1.3.4 流程图
数据流图用于从整体上分析系统的功能及数据流传递过程,E-R图则用于识别系统操作过程中涉及的数据实体及其关系,那么对于某一个具体的操作,我们又该如何刻画其内部的详细流程呢?
流程图就是最经典是一种,它是用于描述程序、系统或过程中各个步骤和流程的图形化工具。它使用不同的图形符号来表示不同的操作和决策,并使用箭头来表示它们之间的顺序和关系。流程图可以帮助人们理解和分析一个过程,从而更好地优化和改进它。表3给出了常用的流程图符号。
| 符号 | 名称 | 说明 |
![]() | 处理 | 能改变数据值或数据位置的加工或部件,例如,程序和人工加工等都是处理 |
![]() | 输入/输出 | 表示输入或输出(或既输入又输出),是一个广义的不指明具体设备的符号 |
![]() | 连接 | 指出转到图的另一部分或从图的另一部分转来,通常在同一页上 |
![]() | 换页连接 | 指出转到另一页图上或由另一页图转来 |
| 数据流 | 用来连接其他符号,指明数据流动方向 | |
![]() | 磁盘 | 磁盘输入输出,也可表示存储在磁盘上的文件或数据库 |
![]() | 显示 | CRT终端或类似的显示部件,可用于输入或输出,也可既输入又输出 |
![]() | 人工输入 | 人工输入数据的脱机处理,例如,填写表格 |
![]() | 人工操作 | 人工完成的处理,例如,会计在工资支票上签名 |
![]() | 辅助操作 | 使用设备进行的脱机操作 |
![]() | 通信链路 | 通过远程通信线路或链路传送数据 |
![]() | 准备 | 表示流程的开始,一个完整的流程图要以该符号开始的 |
![]() | 结束 | 表示流程的结束,一个完整的流程图要以该符号结束 |
![]() | 决策 | 表示流程根据条件分成不同的子处理流程,Y表示满足条件时的流程走向,N表示不满足条件时的流程走向 |
其实,任何复杂的程序,都可以由图11所示的5种基本控制结构组成或嵌套而成。

图11 5种基本的控制结构
当然,流程图可以用于各种不同的领域,包括软件开发、系统设计、流程管理等。它可以帮助开发人员和业务人员更好地理解和沟通复杂的流程和系统,从而提高工作效率和质量。
以“铁路12306”APP中旅客购票流程为例,旅客进入APP后,首先选择始发站、终到站和日期,然后点击“查询车票”按钮,系统显示查询结果,如果有票的话,旅客可以点击相应的票种完成购票操作,如果没有票,旅客可选择继续查询或结束购票。针对上述描述,我们就可以绘制下图所示的流程图:

图12 “铁路12306”APP中旅客购票流程图
为了表达不同角色之间的协同配合过程,更多时候,我们会绘制带有角色泳道的流程图(即泳道图)来描述角色之间的交互过程。 图13给出了档案管理系统中档案管理的操作流程泳道图。
图13 泳道图(带角色的流程图)
流程图发展历史
参考自:https://baijiahao.baidu.com/s?id=1768938752488943708
流程图有着悠久的历史。早在20世纪30年代,贝尔实验室的工程师就用图表来记录电话系统的复杂流程,这就可以视为流程图的雏形。1947年,AT&T的工程师Frank Gilbreth在《电工杂志》上发表了一篇名为《流程图表——铁路设备维护》的文章,是流程图在商业领域应用的前奏。20世纪50年代,工业工程领域大力推广流程图,被广泛用于业务流程的规划、优化和管理。
到了80年代,随着计算机的广泛应用,流程图软件的开发推动了图表技术的发展。智能化的图表软件使设计人员可以更方便、更快速地制作出更为复杂精美的流程图表,将流程图从静态的工具转变成具有交互性的工具。
如今,流程图已成为各大企业和机构常用的工具之一,广泛用于事业流程、数据流程、程序设计等各领域,其发展历程也见证了我们社会和科技的高速发展。而研究、优化、更新流程图的理念,也正是在助力着我们逐步高效和自动化地进行生产和服务。
1.3.5 盒图(N-S图)
在流程图使用过程中,人们发现流程线不一定是必需的,为此,人们设计了一种新的流程图,它把整个程序写在一个大框图内,这个大框图由若干个小的基本框图构成,因为它将所有的图形都限定在一个矩形的“盒子”里,所以叫盒图。盒图是由美国学者Isaac Nassi(艾萨克.纳西)及其学生Ben Shneiderman(本·施奈德曼)于1972年提出的,因此也称为N-S图。图14给出了N-S图包含的基本结构。

图14 N-S图包含的基本结构
注:上图中选择结构(2)表示只有在条件P为真时才执行相应的操作。
依据自顶向下、逐步求精的结构化设计思想,待处理的问题会分解成一些较小的子程序,N-S图对应了上述的思想,利用嵌套的方块来表示副程序。NS图中没有对应Goto指令的表示,和结构化编程中不使用Goto的理念一致。
N-S图几乎是流程图的同构,任何的NS图都可以转换为流程图,而大部分的流程图也可以转换为N-S图。其中只有像Goto指令或是C语言中针对循环的break及continue指令无法用N-S图表示。图15给出了图10对应的N-S图。

图15 “铁路12306”APP中旅客购票流程N-S图
下面是有关N-S图的一些有趣的文章,供大家参考。
https://www.cs.umd.edu/hcil/members/bshneiderman/nsd/(N-S图提出者谈N-S图的诞生过程)
http://www.cs.umd.edu/hcil/members/bshneiderman/nsd/1973.pdf(N-S图原创论文)
https://eagereyes.org/blog/2016/nassi-shneiderman-diagrams(N-S图介绍)
1.3.6 PAD图
PAD图(Problem Analysis Diagram,问题分析图)是1974年由日本日立公司的二村良彦等人提出的又一种主要用于描述软件详细设计的图形表示工具。
它用二维树形结构的图表示程序的控制流,以PAD图为基础,遵循机械的走树规则就能方便地编写出程序,用这种图转换为程序代码比较容易。它既克服了传统的流程图不能清晰表现程序结构的缺点,又不像N-S图那样受到把全部程序约束在一个方框内的限制。图16给出了PAD图包含的基本结构。

图16 PAD图包含的基本结构
同样的,大部分的流程图也可以转换为N-S图。图17给出了图12对应的PAD图。

图17 “铁路12306”APP中旅客购票流程PAD图
1.3.7 PDL语言
PDL(Program Design Language),又称伪代码(Pseudocode),是一种用于描述程序结构和逻辑的语言。它主要用于软件开发过程中的程序设计阶段,帮助程序员组织和规划代码。
使用伪代码的目的是使被描述的算法可以容易地以任何一种编程语言(Pascal,C,Java等)实现。因此,伪代码必须结构清晰、代码简单、可读性好,并且类似自然语言。 使用伪代码, 不用拘泥于具体实现,相比程序语言,它更类似自然语言,可以将整个算法运行过程的结构用接近自然语言的形式(可以使用任何一种你熟悉的文字,关键是把程序的意思表达出来)描述出来。下面是购买车票算法的伪代码示例。
算法名称:购买车票
输入:车次、始发站、终到站、购买数量
输出:错误码,0-购票成功,1-付款失败 2-没有满足要求的车票
处理过程:
1 查询指定车次、始发站、终到站是否有满足数量的车票
2 如果有,则显示选票窗口
2-1 等待用户输入座位类型
2-2 获得用户选择的座位类型
2-3 锁定满足要求的车票
2-4 等待用户付款
2-5 如果在指定时间内付款成功,则标识车票为售出状态,返回0,算法结束;否则,释放车票,返回1,算法结束
3 如果没有,返回2,算法结束
1.3.8 判定表
当模块逻辑中含有复杂的条件组合时,用前面介绍的图形工具描述显得烦琐、不清晰,用判定表与判定树可更加清楚地描述复杂的条件组合与其对应的行为之间的关系。
图18给出了根据乘客的不同情况确定如何收取托运行李费用的判定表,通常一张判定表由四部分组成,左上部分列出所有条件;右上部分是表示各种条件组合的一个矩阵;左下部分是所有可能做的动作;右下部分是与每种条件组合相对应的执行动作。

图18 判定表
1.3.9 判定树
判定树是判定表的变种,也能清晰地表示复杂的条件组合与对应处理之间的关系。判定树的优点在于,它是一种图形表示方式,且不需要任何说明就可以看出其含义,因此,更易被用户理解和掌握。 图19给出了图18对应的判定树:

图19 判定树
1.3.10 层次图
在结构化的软件工程方法中,我们需要基于需求分析阶段得到的数据流图来完成设计并得到系统的层次结构,层次结构可以通过层次图、HIPO图或结构图来表示。
层次图(Hierarchy Diagram),简称H图,用于表示自顶向下分解所得系统的模块层次结构,又可称为模块层次图,也就是我们通常所说的模块图。如图20所示,H图中一个方块代表一个模块,方块内写出标识此模块的处理功能或模块名,为了便于区分,模块名称前可以写上编号;模块间的调用关系,用连接两模块的线表示。

图20 模块图
有关层次图,还需要了解如下内容:
- 从形态特征上来看,上层模块调用下层模块功能,同一层的模块之间没有调用关系。
- 层次图所反映软件结构的层数称为深度。图20的深度为4层。深度在一定意义上反映了软件结构的规模和复杂程度。
- 软件结构中同一层次上的模块总数最多的最大值称为宽度,图20的宽度为8。一般来说,宽度越大系统越复杂。
- 一个模块直接调用的模块数目称为扇出。如图20中模块2的扇出为5。扇出过大说明该模块较复杂,需要控制和协调过多的下级模块,一般适当增加中间层次的控制模块;扇出太小也不好,可以将下级模块进一步分解成若干子功能模块,或者合并到它的上级模块中去,上述的改变不能违背模块独立性原理。经验表明,一个设计好的软件系统的平均扇出是3或4(上界通常是 5~9)。
- 与扇出相对应,扇入用于表示直接调用该模块的上级模块个数。扇入越大则共享该模块的上级模块数目越多,这是符合实际需要的,但是,不能追求高扇入而违背模块独立性原理。
1.3.11 HIPO图
HIPO(Hierarchy plus Input-Process-Output)图是IBM公司于20世纪70年代中期在层次图的基础上推出的一种描述系统结构和模块内部处理功能的工具。HIPO图由层次图和IPO图两部分构成,前者描述整个系统的设计结构以及各类模块之间的关系,后者描述某个特定模块内部的处理过程和输入/输出关系。HIPO图一般由一张总的H图和若干张具体模块内部展开的IPO图组成。
如图21所示,IPO图上部反映模块基本信息,即该模块在总体系统中的位置、所涉及的编码方案、数据文件/数据库、编程要求、设计者和使用者等信息。IPO图的下部主要是在需求分析阶段定义的输入、输出数据流的基础上,对给定模块的输入、输出数据流进行详细定义,重点对该模块的内部处理过程进行描述。

图21 HIPO图
1.3.12 结构图
结构图(Structured Charts,SC)是20世纪70年代中期由美国Yourdon提出的用于表达程序结构的图形表示方法,它能清楚地反映出程序中各模块间的层次调用关系。
如图22所示,与层次图类似,在结构图中也是用一个方块代表一个模块,模块间通过连接线来表示调用关系,连接线上的箭头表示模块间传递的信息,其中实心圆箭头表示传递的控制信息,空心圆箭头表示传递的是数据。

图22 结构图
1.3.13 面向过程的程序设计语言
通过前面的工具我们可以完成对软件的需求分析和设计,那么要想得到满足需求和设计要求的软件,就需要编写程序,根据软件的类型我们可以选择不同的程序设计语言来编写程序。以下是一些常见的程序设计语言分类标准:
- 低级语言和高级语言:低级语言直接操作计算机硬件,例如汇编语言。高级语言更接近人类自然语言,使用更抽象的编程概念和语法,例如Java、Python和C。
- 编译型语言和解释型语言:编译型语言需要通过编译器将源代码转换为机器代码,然后再执行。解释型语言则不需要编译,而是通过解释器一行一行地解释执行源代码。
- 面向过程语言和面向对象语言:面向过程语言以过程或函数为中心进行程序设计,强调过程的顺序和控制流程。面向对象语言则以对象为中心进行程序设计,将数据和操作封装在一起,并支持继承、多态等特性。
- 动态语言和静态语言:动态语言在运行时对变量类型进行检查,可以动态改变类型。静态语言在编译时对变量类型进行检查,类型通常是固定的。
- 命令式语言和函数式语言:命令式语言通过给计算机下达命令的方式进行程序设计。函数式语言则强调使用函数进行程序设计,函数是一种可重用和组合的代码块。
以上分类方式并不是互相排斥的,一个编程语言可能同时具备多个分类的特点。这里我们提到面向过程的程序设计语言,是指在结构化的软件工程方法下,对用于编制软件的程序设计语言的统称,所以也称其为结构化程序设计语言。
在面向过程程序设计中,问题被看作一系列需要完成的任务,函数则用于完成这些任务,每个过程或函数是一个独立的功能模块,通过调用不同的过程或函数来完成程序的整体功能。其概念最早由E.W.Dijikstra在1965年提出,是软件发展的一个重要里程碑,其主要观点是任何程序都可由顺序、选择、循环三种基本控制结构构造。面向过程的程序设计语言注重程序的执行流程和数据的处理,强调程序的结构和算法的优化,适用于较简单的程序和对性能要求较高的场景。常见的面向过程的程序设计语言有C、FORTRAN、COBOL等。
面向过程语言的特点包括:
- 严格的语法:每条语句的书写格式有严格规定,确保程序的正确性和可读性。
- 与硬件无关:设计目标是简化运算过程的描述,使得程序具有普适性,能够转换成不同的机器语言程序。
- 语句接近自然表达式:语句格式接近自然语言的表达方式,使得程序设计更加直观和简单。
- 提供大量函数:通过提供输入输出和复杂运算函数,简化程序设计过程。
- 适合模块化设计:程序可以分解为多个函数,通过函数调用实现复杂问题的解决。













833

被折叠的 条评论
为什么被折叠?



