软件工程笔记4-结构化设计方法

less than 1 minute read

Published:

唯有幽默地看待现实,唯有在生命中轻盈地跳舞,开怀大笑,人才能找到摆脱生存危机的出路,在抵达完善的征程中迈出微小的一步。


结构化设计方法

软件设计的5个原则

1、分而治之。2、模块独立性。3、提高抽象层次。4、复用性设计。5、灵活性设计

  • 分而治之:将大型复杂的问题分解为许多容易解决的小问题(但不是分得越小越好:分的太多,模块之间关系的复杂度也会增加
  • 模块独立性:模块只实现具体的子功能,和软件系统其他模块接口是简单的(使软件便于分工协作开发,容易测试和维护)
  • 提高抽象层次:设计软件时,设计开始时应尽量提高软件的抽象层次,按抽象级别从高到低进行软件设计
  • 灵活性设计:在设计中引入灵活性的方法有:
    • 降低耦合并提高内聚
    • 建立抽象
    • 不要把代码写死
    • 抛出异常
    • 使用并创建可服用的代码

耦合与内聚

模块独立性的度量标准:耦合和内聚

耦合:非直接耦合,数据耦合,控制耦合,特征耦合,公共耦合,内容耦合

原则:尽量使用数据耦合,少使用控制耦合,不适用内容耦合

非直接耦合:模块之间没有关系,联系完全靠主模块控制调用

数据耦合:模块A访问模块B通过简单数据参数交换输入输出信息

特征耦合:一组模块通过参数表传递记录信息(这个记录时某数据结构的子结构,而不是简单变量)

控制耦合:模块A明显控制模块B(通过传送开关,标志,名字等控制信息)

公共耦合:一组模块都访问同一个公共数据环境

内容耦合:一个模块直接访问某一模块数据内部数据

内聚:功能内聚,顺序内聚,通信内聚,过程内聚,时间内聚,逻辑内聚,偶然内聚

功能内聚:模块中各个部分都是完成具体功能必不可少的组成部分

信息内聚:各个功能都在统一数据结构上操作,每一项功能都有一个唯一的入口

通信内聚:一个模块中各功能使用相同的输入或者有相同的输出

时间内聚:一个模块内的处理是相关的,而且必须以特定次序执行

逻辑内聚:模块将几种相关功能组合在一起,模块调用时,由传送给模块的判定参数决定该模块应该执行哪一种功能

巧合内聚:模块各部分之间没有联系,只有松散的联系

结构化设计

软件设计的主要任务:解决“如何做”的问题,需求分析→建立设计模型,分析评估,设计模型,确定这些模型是否能满足要求

软件设计的阶段:

  • 体系结构设计:定义软件的主要结构元素以及之间的关系
  • 接口设计
  • 数据设计:确定文件系统和数据库结构(根据ER图)
  • 过程设计:确定软件各组成部分的算法和数据结构

结构化设计与结构化分析的关系

结构化分析为结构化设计提供了最基本的输入信息

结构化设计方法的实施要点:

(1) 研究、分析和审查数据流图。

(2) 根据数据流图决定问题的类型:变换型和事务型。针对两种不同的类型分别进行分析处理。

(3) 由数据流图推导出系统的初始结构图。

(4) 利用一些启发式原则来改进系统的初始结构图,直到得到符合要求的结构图为止。

(5) 根据分析模型中的实体关系图和数据字典进行数据设计,包括数据库设计或数据文件的设计。

(6) 在上面设计的基础上,并依据分析模型中的加工规格说明、状态转换图进行过程设计。

(7) 制定测试计划。

接口设计利用了数据流图

模块结构及表示

多个模块组成一个软件系统

结构化设计中,函数和子程序都称作模块

模块用矩形框表示,并用模块的名字标记它

  • 模块的分类
  • 模块的结构:树状模块,网状模块
  • 结构图

    精确表达模块结构的图形表示工具

    主要包括:

    1. 模块的调用关系和接口:用单向箭头连接
    2. 模块间的信息传递:数据信息或控制信息
    1. 条件调用和循环调用:条件调用用菱形表示,循环调用以弧形表示
    1. 结构图的形态特征:宽度,深度,扇入,扇出

数据结构及表示

数据结构是数据的各元素之间逻辑关系的表示

典型的数据结构有:标量项,链表,向量,树状结构,网状空间,n维空间

体系结构设计

过程驱动的设计过程(基于数据流方法)

将用数据流图表示的信息转化成程序结构的设计描述

典型的数据流类型和系统结构

变换型数据流事务型数据流(数据流不同,得到的系统结构也不同)

变换数据流的处理流程:取得数据→变换数据→给出数据

事务型数据流:

接受一项输入,根据事务的特点和性质选择分配一个恰当的处理单元给出结果

完成选择分配任务的部分称为 事务处理中心/分派部件

事务型系统结构图的简化:将调度模块归入事务中心模块:

变化型映射方法

系统处理流程总能表示维变化型数据流图

  • 变化分析的步骤
    1. 重画数据流图:如何加工数据(需求分析阶段)→数据如何流动(设计阶段)
    2. 数据流图上区分:逻辑输入,中心变化部分,逻辑输出
    3. 进一步分解,设计系统模块结构的顶端和第一层(不是系统的,是模块的):关键是找到系统树形结构图的根或顶层模块
      • 设计一个主模块,用程序的名字为它命名,将它画在中心变化的位置
      • 第一层:设计输入模块,输出模块,变化模块
    4. 再进行二级分解,设计中下层模块(自顶向下,逐层细化)

### 事务型映射方法

从分析数据流开始,自顶向下,逐层分解,建立系统的结构图

事务分析方法的步骤

(1) 识别事务源。利用数据流图和数据词典,从问题定义和需求分析的结果中,找出各种需要处理的事务。

(2) 规定适当的事务型结构。在确定了该数据流图具有事务型特征之后,根据模块划分理论,建立适当的事务型结构。

(3) 识别各种事务和它们定义的操作。

(4) 注意利用公用模块。

(5) 建立事务处理模块。对每一事务,或对联系密切的一组事务,建立一个事务处理模块。

(6) 对事务处理模块规定它们全部的下层操作模块。

(7) 对操作模块规定它们的全部细节模块。

软件模块结构的改进方法

1. 模块功能的完善化

   一个完整的模块应包括:执行规定的功能;出错处理;若需要返回数据,则应给它的调用者一个返回的“结束标志”

2. 消除重复功能,改善软件结构:

   可能有如下重复的可能

    - 完全相似:直接合并
    - 局部相似:不宜将存在局部相似的两模块合并,而是将他们重复的部分拿出
3. 模块的作用范围应再控制范围内:

   模块A做出的抉择,应只由它的后代(最好是孩子)执行,禁止向上传递抉择信息,避免向下传递信息经过过多模块

   解决方法:合并判定模块到父模块;向上移动模块;移动受判定影响的模块到判定模块控制下

4. 尽量减少高扇出结构,随深度增大扇入

   扇出过大说明缺乏中间层;扇入大说明该模块被大量共享,但要注意是否由于该模块有多个功能引起的

5. 避免使用病态连接(减少内容耦合)

   某模块的子模块A和B应该通过此模块传递数据,而不应该私下传递数据,如:直接病态连接;公共数据域病态连接;通信模块病态连接

6. 模块大小要适中

接口设计

接口设计的依据是数据流图的自动化系统边界

接口设计的主要包含:

模块/软件构建之间的接口;软件与其他软硬件系统之间的接口;软件与人之间的交互设计

数据设计

  • 文件设计(按文件的组织方式分):顺序文件,直接存取文件,索引顺序文件,分区文件,虚拟存储文件
  • 数据库设计

    数据库对象的映射(当分成多个表时的方法):

    • 横切:主表放最近使用的对象,历史记录转移到历史表中
    • 竖切,将经常使用的数学放再主表中,次要属性放在其他表中

过程设计

过程描述工具主要分为:图形工具,表格工具,语言工具

结构程序设计的主要原则:

  1. 使用顺序,选择,重复等有限的基本控制结构表示逻辑逻辑
  2. 控制结构只允许有一个入口和出口
  3. 程序语句可以组成易于识别的块,每个块只有一个入口和出口
  4. 复杂结构应该用基本控制结构进行组合嵌套来实现。
  5. 语言中没有的控制结构,可用一段等价的程序段模拟,该程序段是静态的
  6. 严格控制GOTO语句,
  7. 采用自顶向下(Top-Down)、逐步细化(Stepwise  Refinement)的原则,由粗到细,一步步展开。

程序流程图

N-S图

PAD图

伪代码

自顶向下,逐步细化的设计过程

  • 将复杂问题的解法分解和细化成由若干个模块组成的层次结构;
  • 将每个模块的功能逐步分解细化为一系列的处理。

优点:

  1. 自顶向下、逐步求精方法符合人们解决复杂问题的普遍规律。可提高软件开发的成功率和生产率。
  2. 用先全局后局部,先整体后细节,先抽象后具体的逐步求精的过程开发出来的程序具有清晰的层次结构,因此程序容易阅读和理解。
  3. 程序自顶向下、逐步细化,分解成树形结构。 在同一层的结点上做细化工作,相互之间没有关系,因此它们之间的细化工作相互独立。在任何一步发生错误,一般只影响它下层的结点,同一层的其他结点不受影响。
  4. 程序清晰和模块化,使得在修改和重新设计一个软件时,可复用的代码量最大。
  5. 程序的逻辑结构清晰,有利于程序正确性证明。
  6. 每一步工作仅在上层结点的基础上做不多的设计扩展,便于检查。
  7. 有利于设计的分工和组织工作。