六、结构化开发方法

结构化开发方法是一种经典的软件开发方法,主要包括以下三个部分:

  1. 结构化分析:通过数据流图和数据字典来描述系统功能和数据流程,建立系统的功能模型。
  2. 结构化设计:将数据流图转换为软件结构图,设计出系统的物理模型。
  3. 结构化程序设计:使用顺序、选择和循环三种基本控制结构来编写代码。

核心思想:自顶向下、逐层分解,通过功能分解和抽象来简化复杂系统的设计。
优点:逻辑清晰,易于理解和维护,适合数据处理类系统。
缺点:对大规模复杂项目适应性较差,且需求变更时灵活性不足。

1 系统分析与设计概述

1.1 系统分析概述

1.1.1 系统分析的目的和任务

系统分析旨在通过对现行系统的详细调查,理解组织的管理状况和信息处理流程,为系统开发提供资料,并提交系统方案说明书。其主要内容包括:

  • 业务和数据流程的畅通性与合理性。
  • 数据、业务流程和组织管理间的关系。
  • 原系统管理模式改革和新系统管理方法的可行性。

系统分析的结果包括开发者对组织管理状况的了解、用户需求、数据和业务流程、管理功能和数据指标体系等。

1.1.2 系统分析的主要步骤

系统分析过程主要包括以下几个步骤:

  1. 详细调查:收集数据,建立当前系统的物理模型。
  2. 抽象逻辑模型:从物理模型中抽象出逻辑模型。
  3. 分析与优化:分析当前系统的逻辑模型,提出改进意见和目标。
  4. 建立新系统的逻辑模型:设计新系统的逻辑模型。
  5. 编写系统方案说明书:将分析结果整理成书面资料。

系统分析的目标是将现有系统的物理模型转化为目标系统的物理模型,通过逻辑模型反映系统功能和性质。

1.2 系统设计的基本原理

1.2.1 抽象

  • 定义:抽象是一种设计技术,用于简化复杂现象,突出本质而忽略非本质细节。
  • 目的:将复杂问题简化到可分析、实验或理解的程度。
  • 过程:从软件定义到开发的多个阶段逐步细化,最高抽象层描述问题解法,较低层细化描述。

1.2.2 模块化

  • 定义:模块是程序对象(如数据说明、可执行语句)的集合,可独立开发、测试,最后组合成完整程序。
  • 目的:通过分解复杂问题,使程序结构清晰,易于阅读、理解、测试和修改。
  • 原则:分而治之,将软件分解为若干模块,逐步组合。

1.2.3 信息隐蔽

  • 定义:将程序成分隐蔽或封装在单一模块中,尽量少暴露其内部处理。
  • 目的:提高可修改性、可测试性和可移植性。

1.2.4 模块独立

  • 定义:模块独立指模块完成特定功能,与其他模块联系简单。
  • 衡量标准:耦合性和内聚性。

1)耦合

  • 定义:衡量模块间相对独立性(连接紧密程度)
  • 影响因素:接口复杂度、调用方式、信息类型
  • 目标:低耦合,模块独立性高。

模块独立性与耦合性成反比。

耦合类型(按耦合程度从低到高)

  • 无直接耦合:无直接关联,独立性最高
  • 数据耦合:传递简单数据值
  • 标记耦合:传递数据结构
  • 控制耦合:传递控制变量选择功能
  • 外部耦合:依赖外部环境(设备、协议等)
  • 公共耦合:共享公共数据环境
  • 内容耦合:直接访问内部数据或通过非正常入口进入,独立性最弱

2)内聚

  • 定义:内聚衡量模块内部元素之间的紧密程度,内聚性越强,模块独立性越高。
  • 目标:高内聚,模块功能单一,独立性强。

内聚类型(按内聚程度从低到高)

  • 偶然内聚:元素间无关联,独立性最弱
  • 逻辑内聚:执行逻辑上相似功能,通过参数选择
  • 时间内聚:组合需同时执行的动作
  • 过程内聚:完成多个任务,任务按特定顺序进行
  • 通信内聚:元素在同一个数据结构上操作,或使用相同输入/输出
  • 顺序内聚:元素密切相关且需顺序执行,前一元素输出是下一输入
  • 功能内聚:所有元素共同完成一个功能,缺一不可,独立性最强

1.3 系统总体结构设计

1.3.1 系统设计原则

  1. 分解-协调原则:将复杂系统分解为多个子系统,处理过程中协调各子系统。
  2. 自顶向下设计:先设计顶层模块功能,再逐步细化下层模块功能。
  3. 信息隐蔽、抽象:上层模块定义下层模块功能和协调关系,隐藏实现细节。
  4. 一致性原则:保证软件设计具有统一规范和标准的文件模式。
  5. 明确性原则:模块功能和接口明确,消除多余功能和无用接口。
  6. 低耦合、高内聚:模块间耦合度低,内聚性高。
  7. 模块的扇入和扇出合理:模块直接调用其他模块的数量要合理。
  8. 模块规模适当:模块规模适中,功能单一。

1.3.2 子系统划分原则

  1. 具有相对独立性:子系统功能和信息相对独立,提高开发效率和软件质量。
  2. 接口简单:子系统间接口简单,易于理解和维护。
  3. 信息隐蔽:子系统内部数据隐蔽,减少外部访问。
  4. 考虑后续管理:子系统划分应支持后续扩展和维护。
  5. 划分便于实现:子系统划分应便于分阶段实施。
  6. 充分利用资源:子系统划分应考虑资源的合理利用。

1.3.3 系统模块结构设计

  1. 模块的概念:模块是系统的组成单位,具有输入输出、处理功能、内部数据和程序代码。
  2. 模块结构图:用图形表示系统模块结构,遵循分级分类和建档归档原则。模块结构图由模块、调用(箭头)、数据(带空心圆的箭头)、控制信息(带实心圆的箭头)和转接符号组成。模块结构图只关心模块的外部属性。
  3. 模块调用:模块间调用关系用箭头表示,支持判断调用和循环调用。
  4. 模块间的传递:模块间传递数据和控制信息,用转接符号表示复杂传递。

1.3.4 数据存储设计

  1. 数据存储设计的重要性:信息系统需要存储和管理大量数据,建立良好的数据存储结构是关键。
  2. 数据存储结构和数据库文件:根据数据类型、使用要求、安全性和性能确定数据存储结构和文件形式。
  3. 数据存储分布和安全性:考虑数据在网络环境下的分布问题和数据的安全性要求。

1.4 系统文档

系统文档作为系统建设过程的“痕迹”,对系统维护、开发人员与用户的交流具有重要意义。规范化的文档不仅表明系统遵循工程化开发,还能确保系统质量,并降低因人员变动带来的风险。

1.4.1 文档分类

  1. 软件开发文档:包括系统分析、设计、测试等阶段产生的文档。
  2. 硬件与网络文档:涵盖硬件采购和网络设计相关文档。
  3. 不规范文档:包括建设过程中的来往文件、会议纪要、会计单据等。
  4. 实施与培训文档:涵盖系统实施记录、程序资料和培训教程。

1.4.2 文档的作用

  1. 用户与系统分析人员沟通:通过可行性研究报告、总体规划报告等文档,确保用户需求被正确理解。
  2. 开发人员与项目管理人员沟通:借助系统开发计划、PERT 图、甘特图等项目管理文件,实现工作顺利交接。
  3. 测试人员与开发人员沟通:系统测试人员依据系统方案说明书、测试计划等文档进行测试,并撰写测试报告。
  4. 开发人员与用户沟通:用户通过用户手册和操作指南运行系统。
  5. 开发人员与维护人员沟通:系统设计说明书和开发总结报告为系统维护和升级提供依据。
  6. 用户与维护人员沟通:用户记录系统运行问题,形成维护建议,维护人员据此进行系统维护和升级。

2 结构化分析方法

2.1 结构化分析方法概述

结构化分析是一种面向数据流的软件开发方法,通过自顶向下的逐层分解和抽象来分析和建模复杂问题。其核心思想是将大问题分解为小问题,逐步解决。结构化分析的主要成果包括分层的数据流图、数据词典、加工逻辑说明和补充材料。

2.2 数据流图

2.2.1 数据流图的基本图形元素

数据流图(DFD)是一种用于描述系统数据流程的图形工具,其基本元素包括:

  1. 数据流:表示数据的流向,命名需明确,反映数据含义。由固定成分的数据组成,表示数据流向,如从加工到加工、加工到数据存储等。
  2. 加工:描述输入数据流到输出数据流的转换过程,需有名字和编号。必须有一个输入数据流和一个输出数据流,常见错误包括“黑洞”(无输出)、“灰洞”(输入不足以产生输出)。
  3. 数据存储:用于存储数据,支持数据的读写操作。可用文件系统或数据库实现,存储介质多样。
  4. 外部实体:表示系统之外的对象,标识数据的源和宿。数据源和宿可以为同一个。

2.2.2 数据流图的扩充符号

在数据流图(DFD)中,扩充符号用于描述多个数据流之间的关系:

  1. 星号(*)
    • 表示数据流之间存在“与”关系。
    • 输入流:所有输入数据流全部到达后才能进行加工处理。
    • 输出流:加工结束后同时产生所有的输出数据流。
  2. 加号(+)
    • 表示数据流之间存在“或”关系。
    • 输入流:任何一个输入数据流到达后就能进行加工处理。
    • 输出流:加工处理的结果是至少产生其中一个输出数据流。
  3. 异或(⊕)
    • 表示数据流之间存在“互斥”关系。
    • 输入流:当且仅当其中一个输入流到达后才能进行加工处理。
    • 输出流:加工处理的结果是仅产生这些输出数据流中的一个。

2.2.3 数据流图的层次结构

数据流图可以按照层次结构进行绘制,以简化复杂系统的表示:

  1. 层次结构
    • 顶层图:只有一张图,包含一个加工,代表整个软件系统,描述系统与外界的数据流。
    • 0 层图:顶层图中的加工分解后的图,也只有一张。
    • 底层图:所有加工不再分解的图。
    • 中间层:至少有一个加工被分解成子图的图。
  2. 图和加工的编号
    • 父图和子图
      • 父图中的加工分解成子图。
      • 每张子图对应一张父图。
    • 编号规则
      • 顶层图中的加工不编号。
      • 0 层图中的加工编号为 1、2、3 等。
      • 子图的编号与父图中被分解的加工号相同。
      • 子图中的加工编号为父图加工号后跟 .1、.2、.3 等。

2.2.4 分层数据流图的画法

  1. 画系统的输入和输出
  • 顶层图:描述系统从哪些外部实体接收数据流,以及系统发送数据流到哪些外部实体。
  • 输入输出:顶层图中通常没有数据存储,数据流即为系统的输入/输出信息。
  1. 画系统的内部
  • 分解加工:将顶层图的加工分解为若干子加工,并用数据流连接这些加工。
  • 0 层图:顶层图加工分解后的图,描述系统的输入输出转换为内部处理。
  1. 确定加工
  • 功能分解:根据功能分解确定子加工。
  • 业务流程:根据业务处理流程确定子加工。
  1. 确定数据流
  • 数据流:将若干数据看作一个整体,通常实际工作环境中的表单是一种数据流。
  1. 确定数据存储
  • 数据存储:在子图中,如果父图中的加工存在流向数据存储的数据流或从数据存储流向加工的数据流,则在子图中画出相关的数据存储和数据流。
  1. 确定源和宿
  • 源和宿:在 0 层图和其他子图中不必画出源和宿,但有时为增加可读性,可以重复画在 DFD 的不同位置。
  1. 画加工的内部
  • 分解复杂加工:将复杂加工分解为多个子加工,直至所有未分解的加工足够简单。

2.2.5 分层数据流图的审查

2.2.5.1 分层数据流图的一致性和完整性

1)一致性

  1. 父图与子图的平衡
    • 子图的输入/输出数据流必须与父图中对应加工的输入/输出数据流一致。
    • 如果父图中某加工的一条数据流对应子图中的多条数据流,且这些数据流的组合等于父图中的数据流,则仍平衡。
  2. 数据守恒
    • 加工的输出数据流必须来自输入数据流或通过处理生成。
    • 检查未使用的输入数据项,可能暗示多余数据或潜在错误。
  3. 局部数据存储
    • 数据存储应在多加工之间共享时绘制在 DFD 中。
    • 若数据存储仅与一个加工交互且未在父图中出现,则不应绘制。
  4. 数据流命名
    • 加工的输入和输出数据流不能同名,即使组成相同也需不同名。

2)完整性

  1. 输入输出完整性 - 每个加工至少有一个输入和一个输出数据流。
  2. 数据存储操作 - 每个数据存储至少有一个加工进行读操作和另一个进行写操作。
  3. 命名规范 - 所有数据流、加工、数据存储和外部实体必须有明确的命名。
  4. 基本加工规约 - 每个基本加工应有明确的加工规约。
2.2.5.2 构造分层 DFD 时的注意事项
  1. 适当命名 - 名字应反映对象的整体含义,避免使用空洞或含义不清的名字。
  2. 画数据流而非控制流 - 数据流图应强调数据流,而非控制流。
  3. 避免过多数据流 - 加工有过多数据流时,重新分解为多个子图。
  4. 分解均匀 - 理想分解是将加工分解为大小均匀的子加工。
  5. 分解程度 - 参照“7±2”原则,分解应自然、合理、清晰。
  6. 先考虑稳定状态 - 集中精力考虑稳定状态下的问题,忽略琐碎细节。
  7. 准备重画 - 复杂系统的分层 DFD 可能需要多次重画和修改。
2.2.5.3 分解的程度
  1. 7±2原则 - 每张图中的加工数量控制在 7±2 范围内。
  2. 自然分解 - 分解应自然,概念上合理、清晰。
  3. 减少层次 - 适当增加子加工数量以减少层次,提高易理解性。
  4. 上层多分解,下层少分解 - 上层分解较快(多分几个加工),下层分解较慢(少分几个加工)。
  5. 均匀分解 - 分解应均匀,避免部分加工分解过多而部分分解过少。

6.2.3 数据词典 (DD)

6.2.3.1 数据词典的内容

数据词典是对数据流图中各成分的说明,包括以下四类条目:

  1. 数据流条目:描述数据流的组成。
    • 使用符号定义,如 x = a + b 表示 xab 组成。
    • 常用符号包括 =, +, [...], {...}, m{...}n, [...] 等。
  2. 数据存储条目:定义数据存储的内容。
  3. 数据项条目:描述不可再分的数据单位。
  4. 基本加工条目:说明加工的处理逻辑。
6.2.3.2 数据词典管理

数据词典管理包括存储、排序、查找和统计等功能。它确保数据词典与数据流图的一致性。

6.2.3.3 加工逻辑的描述

加工逻辑也称为“小说明”。常用的加工逻辑描述方法有三种:

  1. 结构化语言
    • 外层:描述控制结构,使用顺序、选择和重复结构。
      • 顺序结构:祈使语句的顺序排列。
      • 选择结构:使用 IF-THEN-ELSE-ENDIF 等关键词。
      • 重复结构:使用 DO-WHILE-ENDDO 等关键词。
    • 内层:使用自然语言短语,结合数据词典中的名词和有限的自定义词。
  2. 判定表
    • 由条件定义、条件取值组合、动作定义和动作组合四部分组成。
    • 用于描述复杂的条件组合与动作之间的对应关系。
  3. 判定树
    • 判定表的变形,通常更直观,易于理解和使用。

3 结构化设计方法

结构化设计(StucturedDesign,SD)方法是一种面向数据流的设计方法,它可以与 SA 方法衔接。基本思想是将系统设计成由相对独立、功能单一的模块组成的结构。用结构图(Suructure Chart)来描述软件系统的体系结构,指出一个软件系统由哪些模块组成,以及模块之间的调用关系。

3.1 结构化设计的步骤

  1. 建立初始结构图
  • 功能分解:将软件视为一个大的功能模块,逐步分解为较小的功能模块,直到得到不可再分的底层模块。
  • 设计准则:遵循自顶向下、逐步求精、信息隐蔽、高内聚低耦合等原则。
  • 模块大小:建议模块代码量在 50-100 行之间。
  1. 对结构图的改进
  • 优化设计:根据设计准则,改进初始结构图中的不合理部分。
  • 调整模块分解:确保模块分解合理,符合设计原则。
  1. 书写设计文档
  • 设计规格说明:描述每个模块的功能、接口、约束和限制。
  • 模块开发卷宗:必要时为模块建立详细文档。
  1. 设计评审
  • 评审内容:对设计结果和文档进行评审,确保设计质量。

3.2 数据流图到软件体系结构的映射

3.2.1 信息流的类型

数据流图(DFD)中的信息流可分为两种类型:变换流事务流

  1. 变换流
  • 特点:信息流经过输入通路进入系统,转换为内部形式,经变换中心处理后,再通过输出通路转换为外部形式离开系统。
  • 结构:可分为输入、变换(主加工)和输出三部分。
  1. 事务流
  • 特点:信息流到达事务中心后,根据输入事务类型选择相应的动作序列(活动流)执行。
  • 结构:有明显的事务中心,各活动流从事务中心呈辐射状流出。

3.2.2 变换分析

变换分析用于将变换流型 DFD 转换为程序结构图。

  1. 第一级分解
  • 顶层模块:代表整个系统的功能。
  • 输入控制模块:接收所有输入数据。
  • 变换控制模块:实现输入到输出的变换。
  • 输出控制模块:产生所有输出数据。
  1. 第二级分解
  • 输入控制模块的分解:沿每条输入通路,将加工映射为低层模块。
  • 输出控制模块的分解:沿每条输出通路,将加工映射为低层模块。
  • 变换控制模块的分解:根据DFD中变换部分的具体情况进行设计。

3.2.3 事务分析

事务分析用于将事务流型 DFD 转换为程序结构图。

1 高层结构

  • 顶层模块:代表整个系统的功能。
  • 接收模块:接收输入数据,对应输入流。
  • 发送模块:调度模块,控制下层活动模块。
  • 活动流模块:每条活动流对应一个模块,作为该活动流程序结构的顶层模块。

2 进一步分解

  • 接收模块的分解:类似于变换分析中的输入控制模块分解。
  • 活动流模块的分解:根据流特性(变换流或事务流)采用相应的分析方法进行分解。

3.2.4 SD 方法的设计步骤

  1. 复查并精化数据流图。
  2. 确定 DFD 的信息流类型(变换流或事务流)。
  3. 根据流类型分别实施变换分析或事务分析。
  4. 根据系统设计原则优化程序结构图。

4 WebApp 分析与设计

4.1 WebApp 的特性

  1. 网络密集性
    • WebApp 部署在网络上,服务于不同客户群体。
    • 提供开放访问(如互联网)或受限访问(如企业内联网)。
  2. 并发性
    • 支持大量用户同时访问。
    • 用户使用模式差异大。
  3. 无法预知的负载量
    • 用户数量可能每天都有数量级的变化。
    • 需要灵活应对负载波动。
  4. 性能
    • 用户对响应时间敏感,性能不佳可能导致用户流失。
  5. 可用性
    • 用户期望 24/7 全天候访问。
    • 高可用性是热门 WebApp 的基本要求。
  6. 数据驱动
    • 提供文本、图片、音频、视频等超媒体内容。
    • 常访问外部数据库以获取信息。

4.2 WebApp 需求模型

  1. 内容模型
  • 定义:描述 WebApp 提供的所有内容,包括文字、图形、图像、音频和视频。
  • 内容对象:网页中所有对最终用户可见的实体,如产品描述、新闻文章、图片等。
  • 数据树:用于定义内容对象的层级关系,帮助发现遗漏和不一致的内容。
  1. 交互模型
  • 描述:用户与 WebApp 之间的交互方式。
  • 组成元素
    • 用例:描述系统功能。
    • 顺序图:展示用户与系统交互的步骤。
    • 状态图:描述系统动态行为。
    • 用户界面原型:展示界面布局和交互机制。
  1. 功能模型
  • 功能分类
    • 用户可观察功能:直接由用户启动的功能。
    • 分析类操作:支持功能实现的底层操作。
  • 工具:UML 活动图用于描述处理细节。
  1. 导航模型
  • 定义:定义 WebApp 的导航策略。
  • 考虑因素
    • 元素的导航优先级。
    • 用户导航行为的引导。
    • 导航错误处理。
    • 导航方式选择。
    • 导航历史记录。
    • 导航地图或菜单的可用性。
    • 用户行为与 WebApp 元素的匹配。
    • 导航快捷方式。
    • 外部链接处理。
  1. 配置模型
  • 定义:描述 WebApp 的运行环境和基础设施。
  • 复杂 WebApp:可能涉及多服务器负载均衡、高速缓存、远程数据库等配置。

4.3 WebApp 设计

  1. 架构设计
  • 目标:构建多层架构,包括用户界面层、控制器层和模型层。
  • 典型架构:模型-视图-控制器(MVC),分离功能与内容。
  1. 构件设计
  • 内容设计:组织内容对象,适合 WebApp 特性。
  • 功能设计:开发功能构件,确保与用户交互一致。
  1. 内容设计
  • 结构类型
    • 线性结构:用于可预测顺序内容。
    • 网格结构:组织二维内容。
    • 层次结构:垂直或水平组织内容。
    • 网络结构:超链接连接网页。
  1. 导航设计
  • 定义路径:确保用户可访问内容和功能。
  • 导航机制:包括导航链接、导航条、标签和网站地图。

5 用户界面设计

5.1 用户界面设计的黄金原则

Theo Mandel 提出了三条“黄金原则”:用户操纵控制、减轻用户的记忆负担、保持界面一致。

  1. 用户操纵控制
  • 不强迫用户进入不必要的动作:交互模式不应妨碍用户正常使用。
  • 提供灵活的交互方式:支持多种交互机制,如键盘、鼠标等。
  • 允许中断和撤销操作:用户应能随时中断操作并撤销。
  • 允许定制交互:高级用户可定制界面以提高效率。
  • 隐藏内部技术细节:用户不应接触操作系统等底层细节。
  • 直接操纵屏幕对象:提供直观的对象操作方式。
  1. 减轻用户的记忆负担
  • 减少短期记忆要求:通过可视提示帮助用户回忆。
  • 建立有意义的默认值:提供合理的初始设置,允许用户自定义。
  • 定义直观的快捷方式:快捷方式应易于记忆。
  • 基于真实世界的视觉布局:使用熟悉的象征和流程。
  • 逐步揭示信息:按需提供详细信息,避免信息过载。
  1. 保持界面一致
  • 提供环境指示器:帮助用户了解当前任务环境。
  • 在应用系统内保持一致:使用统一的设计规则和交互机制。
  • 遵循用户期望的交互模型:不要随意改变用户已习惯的交互方式。

5.2 用户界面的分析与设计

5.2.1 用户界面分析和设计模型

  1. 设计模型:包括软件的数据结构、体系结构、界面和过程表示。
  2. 用户模型:描述最终用户的特点,如年龄、性别、能力和背景。
  3. 心理模型:用户对系统的主观映像,影响系统使用感受。
  4. 系统映像:系统的外在表示和支撑信息,应与用户心理模型一致。

5.2.2 用户界面分析和设计的过程

  1. 界面分析及建模:识别用户类型和需求。
  2. 界面设计:定义界面对象和动作,满足用户目标。
  3. 界面构造:创建原型并迭代开发。
  4. 界面确认:评估界面功能、易用性和用户接受度。

5.3 用户界面设计问题

  1. 系统响应时间:关注时间和可变性,保持稳定性。
  2. 帮助设施:提供多种帮助方式,确保用户能获取支持。
  3. 错误信息处理:使用用户友好的语言,提供恢复建议。
  4. 菜单和命令标记:确保命令清晰、可定制,与功能一致。

加餐和总结

数据流图是重点