软件体系结构 - 系统分析与设计(1.结构化方法)

简介: 【4月更文挑战第5天】软件体系结构 - 系统分析与设计(1)

结构化系统分析和设计


结构化分析SA

图形化建模工具

  • 数据流图(DFD,Data Flow Diagrams):是结构化分析的主要建模工具,用以描绘系统的数据处理流程。DFD包含加工(处理)、数据流、数据存储和外部实体等元素,通过图形化方式直观展现数据如何在系统中流动和转换。
  • 数据字典(DD,Data Dictionary):是对DFD中涉及的所有数据元素的详细说明,包括数据项的名称、含义、数据类型、长度、取值范围、来源、去向等信息,确保对数据的理解一致。


结构化设计SD

  1. 自顶向下、逐步求精
  • 结构化分析采用自顶向下的分解策略,即将复杂的系统整体逐步分解为更小、更易管理的部分(子系统或模块),直至达到足够详细的层次。
  • 逐步求精意味着在每个分解层次上,对系统行为的描述都比上一层更为具体,逐步细化需求细节。
  1. 面向数据流
  • 结构化分析以数据流作为理解和描述系统行为的核心。数据流代表了系统内外部之间传输的数据,通过分析数据如何在系统内被接收、处理、存储和输出,来刻画系统的功能。
  1. 概要设计:确定软件系统的结构,对系统进行模块划分,确定每个模块的功能和接口,以及调用关系。(模块结构图/系统结构图)
  2. 详细设计:为每个模块设计实现细节.
  1. 图形工具:业务流程图、程序流程图(程序框图)、PAD图、NS流程图(盒图)
  2. 表格工具:表格
  3. 语言工具:伪码、PDL(结构化语言)
  1. 耦合

模块的耦合类型是指在软件设计中用来描述不同模块间相互依赖关系紧密程度的不同类别。耦合度反映了模块间相互关联的复杂程度和影响范围,它直接影响着软件的可理解性、可维护性、可测试性和可重用性。以下是常见的模块耦合类型,按照耦合强度从高到低排列:

  1. 内容耦合(Content Coupling)
  • 最强的耦合形式,一个模块直接访问或修改另一个模块的内部数据、代码或控制结构。
  • 示例:直接引用其他模块的私有变量、函数内部细节,或者一个模块的执行流直接跳入另一个模块的内部。
  1. 公共耦合(Common Coupling)
  • 模块间通过共享全局数据(如全局变量、共享数据区、数据库表等)进行通信。
  • 示例:多个模块读写同一全局变量或访问同一数据库表,对这些公共资源的任何改动可能影响所有依赖它的模块。
  1. 控制耦合(Control Coupling)
  • 一个模块通过传递控制信号(如标志、开关、状态码等)来影响另一个模块的行为或流程。
  • 示例:一个模块向另一个模块传递一个条件标志,接收模块根据该标志执行不同的分支逻辑。
  1. 外部耦合(External Coupling)
  • 模块间由于依赖于相同的外部环境(如硬件接口、操作系统服务、特定文件格式等)而产生的耦合。
  • 示例:两个模块都直接操作同一台打印机或使用同一种特定文件格式进行数据交换。
  1. 数据耦合(Data Coupling)
  • 模块间仅通过参数传递数据,且传递的数据与数据结构无关,接收模块无需知道数据的具体来源和产生方式。
  • 示例:函数调用时,调用者仅向被调用者传递所需数据,而不涉及任何控制信息或对对方内部结构的了解。
  1. 标记耦合(Stamp Coupling,有时也称为特征耦合)
  • 模块间通过数据结构(如数组、记录、对象等)传递信息,接收模块必须了解或依赖于该数据结构的某些特定字段(标记)。
  • 示例:一个模块向另一个模块传递一个结构体,后者仅使用其中一部分字段,但必须处理整个结构体。
  1. 非直接耦合(Non-Direct Coupling,也称为无耦合或非直接连接)
  • 最弱的耦合形式,模块间不存在直接的依赖关系,它们之间的交互完全通过中介模块(如接口、中间件、消息队列等)进行。
  • 示例:模块通过消息传递机制发送和接收消息,不需要知道消息的发送者或接收者的具体实现细节。

在实际软件设计中,目标是尽量减少强耦合(如内容耦合和公共耦合),倾向于使用弱耦合(如数据耦合和非直接耦合),以提高模块的独立性和软件的整体可维护性。遵循“高内聚、低耦合”的原则,设计人员可以通过合理划分模块边界、使用接口抽象、减少全局变量、采用设计模式等手段来降低模块间的耦合度。

  1. 内聚

模块的内聚类型是指在一个模块内部,各个组成元素(如函数、子程序、数据结构等)之间相互关联的紧密程度和一致性。内聚度是衡量模块内部功能集中度和独立性的重要指标,对于软件的可读性、可维护性、可复用性有着显著影响。以下是常见的模块内聚类型,按照内聚度从低到高排列:

  1. 偶然内聚(Coincidental Cohesion)
  • 最弱的内聚形式,模块内部的元素之间缺乏明显的逻辑联系,它们只是因为某种偶然原因(如历史遗留、程序员方便等)被放在一起。
  • 示例:一个模块中包含了几个不相关的功能,如打印报表、更新用户信息、计算税率等,这些功能之间没有直接关联。
  1. 逻辑内聚(Logical Cohesion)
  • 模块内部的元素在逻辑上具有某种相似性或相关性,但并不直接支持同一高层功能。
  • 示例:一个模块包含多个与图形处理相关的函数(画线、填充矩形、绘制文字),这些函数虽然都与图形有关,但各自服务于不同的应用场景,没有共同的目标。
  1. 时间内聚(Temporal Cohesion)
  • 模块内部的元素必须在同一时间段内执行,但它们在功能上可能并不相关。
  • 示例:一个模块负责启动应用程序时的初始化工作,包括打开数据库连接、加载配置文件、创建日志文件等,这些任务在时间上紧密关联,但各自服务于不同的系统组件。
  1. 过程内聚(Procedural Cohesion)
  • 模块内部的元素按特定的步骤或顺序执行,形成一个连贯的工作流程,但这些步骤可能处理的是不同的数据或服务于不同的子功能。
  • 示例:一个模块负责处理订单流程,包括验证订单信息、计算总价、扣减库存、生成发票等,这些步骤有明确的执行顺序,但各自关注订单处理的不同方面。
  1. 通信内聚(Communicational Cohesion)
  • 模块内部的元素操作或处理的是相同的数据集,或者使用相同的输入数据或产生相同的输出数据。
  • 示例:一个模块包含多个函数,它们都对同一个数据库表进行增删改查操作,尽管各自处理的具体业务逻辑不同,但都围绕同一数据源。
  1. 顺序内聚(Sequential Cohesion)
  • 模块内部的元素按严格的顺序执行,每个元素的输出是下一个元素的输入,它们共同完成一个连续的任务。
  • 示例:一个图像处理模块,包含依次进行的灰度化、滤波、边缘检测等操作,这些操作之间有明确的前后依赖关系。
  1. 功能内聚(Functional Cohesion)
  • 最强的内聚形式,模块内部的所有元素紧密协作,共同完成一个单一、明确的功能,且元素间联系紧密,缺一不可。
  • 示例:一个模块负责计算圆的面积,只包含一个函数,输入圆的半径,返回计算结果。这个模块只做一件事,功能高度集中。


结构化编程(结构化程序设计)SP

结构化程序设计(Structured Programming)是一种编程范式,强调使用清晰、简洁、有序的控制结构来组织程序逻辑,以提高代码的可读性、可维护性和可靠性。其核心思想是通过限制或避免使用复杂的控制流(如无条件跳转、嵌套过深的循环等),使得程序的执行流程易于理解和分析。结构化程序设计主要基于以下几种基本控制结构:

1. 顺序结构(Sequence)

这是最简单的结构,程序中的语句按照书写的顺序逐条执行。没有分支或循环,一条语句执行完毕后接着执行下一条。

2. 选择结构(Selection)

也称为分支结构,用于根据某个条件判断来决定执行不同的代码路径。主要有以下两种形式:

  • 单路选择(If Statement): 如果条件满足,则执行某段代码;否则跳过该段代码,继续执行后续代码。
  • 双路选择(If-Else Statement): 如果条件满足,则执行一段代码;否则执行另一段代码。无论条件是否满足,总是执行其中的一个分支。

3. 循环结构(Iteration)

用于重复执行一段代码,直到满足某个终止条件为止。常见的循环结构包括:

  • 当型循环(While Loop): 当给定的条件为真时,循环体内的代码被执行;每次循环结束后检查条件,若仍为真则继续循环。
  • 直到型循环(Until Loop 或 Do-While Loop): 先执行一次循环体,然后在每次循环结束后检查条件,若条件尚未为真则继续循环。
  • 计数型循环(For Loop): 通常包含初始值设定、循环条件和迭代增量三个部分,用于在已知循环次数的情况下遍历一个范围内的值。

4. 多路选择(Switch Statement)

在某些编程语言中,提供了switch语句作为选择结构的扩展,允许根据一个表达式的值匹配多个可能的分支(case),每个分支对应特定的代码块。此外,通常会有默认分支(default case)处理未明确匹配的情况。

5. 子程序(Subroutines)

结构化程序设计提倡将复杂任务分解为一系列可重用的子程序(如函数、方法、过程等)。子程序具有明确的接口(参数列表和返回值),封装了独立的逻辑单元,有助于降低代码复杂性,提高代码复用性。子程序的调用和返回构成了程序的基本控制流。

特点与优点

  • 清晰逻辑:通过有限的控制结构,程序的执行路径直观明了,易于理解和预测。
  • 模块化:通过子程序实现模块化编程,将复杂问题分解为小的、可管理的部分。
  • 减少错误:避免了无条件跳转(如GOTO语句)可能导致的混乱和难以调试的“面条代码”(spaghetti code)。
  • 易于测试:结构化的程序更容易编写测试用例,确保各部分功能正确无误。
  • 便于维护:由于逻辑清晰、结构规范,后期修改或添加功能时,可以更精确地定位和修改代码,降低维护成本。

结构化程序设计原则是现代编程实践的基础,虽然面向对象编程、函数式编程等更高级的编程范式提供了更多抽象和组织代码的方式,但结构化编程的核心理念仍然被广泛应用于各类软件开发中。

程序=算法+数据结构


相关文章
|
6月前
|
Devops 测试技术 项目管理
软件体系结构 - 需求工程
【4月更文挑战第3天】软件体系结构 - 需求工程
71 11
|
6月前
|
存储 测试技术 BI
软件体系结构 - 系统分析与设计(2.面向对象方法)
【4月更文挑战第6天】软件体系结构 - 系统分析与设计(2)
93 0
|
6月前
|
缓存 编译器
软件体系结构 - 指令集架构
软件体系结构 - 指令集架构
88 0
|
6月前
|
前端开发 Java 数据库
软件体系结构 - 软件构件
软件体系结构 - 软件构件
175 0
|
存储 算法 搜索推荐
一文探究系统分析与设计的逻辑性
「软件分析」与「软件设计」这样的词眼经常听到,然而要真正理解「软件分析」和「软件设计」的本质是比较难的,本文带你了解软件分析与设计的「逻辑性」到底是什么。
1016 24
|
4月前
|
数据库
系统分析与设计问题之什么是软件分析和软件设计
系统分析与设计问题之什么是软件分析和软件设计
|
4月前
|
数据库
系统分析与设计问题之在软件开发中,为什么需要考虑变化
系统分析与设计问题之在软件开发中,为什么需要考虑变化
|
6月前
|
监控 测试技术 项目管理
软件体系结构 - 软件项目管理
【4月更文挑战第9天】软件体系结构 - 软件项目管理
84 0
|
运维 架构师 测试技术
软件设计的方法论:软件为什么要建模?
软件设计的方法论:软件为什么要建模?
346 0
软件设计的方法论:软件为什么要建模?
|
存储 安全 数据库
【软件工程基础】系统设计——概要设计
【软件工程基础】系统设计——概要设计
869 0