[软件工程] 总体设计(概要设计或初步设计)

总体设计

  • 一、设计过程
    • (一) 9个步骤
      • 1. 设想供选择的方案
      • 2. 选取合理的方案
      • 3. 推荐最佳方案
      • 4. 功能分解
      • 5. 设计软件结构
      • 6. 设计数据库
      • 7. 制定测试计划
      • 8. 书写文档
  • 二、设计原理
    • (一) 模块化
    • (二)抽象
    • (三)逐步求精
    • (四) 信息隐藏和局部化
    • (五) 模块独立
  • 三、启发规则
  • 四、描绘软件结构的图形工具
    • (一) 层次图和HIPO图
    • (二)结构图
    • (三)结构图
  • 五、 面向数据流的设计方法
    • (一)概念
    • (二) 变换分析
    • (三)事务分析技术
    • (四) 设计优化

基本目的:“概括回答地说就是,系统应该如何实现?”

工作内容: 将划分出组成系统的物理元素——程序、文件、数据库、人工过程和文档等黑盒子级“产品”。黑盒子里的具体内容将在以后仔细设计。

重要任务: 是设计软件的结构——模块组成,以及这些模块相互间的关系。
首先根据需求分析阶段得到的数据流图寻找实现目标系统的各种不同的方案,为每个合理的方案准备一份系统流程图,列出组成系统的所有物理元素,进行成本/效益分析,并且制定实现这个方案的进度计划。选出一个最佳方案向用户推荐。

必要性(详细设计之前): 站在全局高度上,花较少成本,从较抽象的层次上分析对比多种可能的系统实现方案和软件结构,从中选出最佳方案和最合理的软件结构,降低成本、提高质量。

一、设计过程

  • 系统设计阶段:确定系统的具体实现方案;
  • 结构设计阶段:确定软件结构。

(一) 9个步骤

典型的总体设计过程包括下述9个步骤

1. 设想供选择的方案

  • 考虑各种可能的实现方案从中选出最佳
  • 根据系统的逻辑模型,分析比较不同的物理实现方案,选出最佳方案,提高系统的性/价比。
  • 由需求分析的数据流图作为出发点,把数据流图中的处理分组的各种可能的方法,抛弃在技术上行不通的分组方法,提供可供选择的物理系统。

2. 选取合理的方案

选取低成本、中等成本和高成本的三种方案,对每个合理的方案分析员都应该准备下列4份资料
(1) 系统流程图;
(2) 组成系统的物理元素清单;
(3) 成本/效益分析;
(4) 实现这个系统的进度计划。

3. 推荐最佳方案

推荐一个最佳的方案,并且为推荐的方案制定详细的实现计划。
提请使用部门负责人进一步审批之后,将进入总体设计过程的下一个重要阶段——结构设计。

4. 功能分解

  1. 程序和文件(或数据库)是组成系统的主要元素,需要设计决定。
  2. 对程序的设计通常分为两个阶段完成:结构设计和过程设计。
  3. 结构设计确定程序由哪些模块组成,以及这些模块之间的关系(总体设计);
  4. 过程设计确定每个模块的处理过程(详细设计)。
  5. 为确定软件结构,首先需要从实现角度把复杂的功能进一步分解。
  6. 经过分解之后应该使每个功能对大多数程序员而言都是明显易懂的。
  7. 功能分解导致数据流图的进一步细化,同时还应该用IPO图或其他适当的工具简要描述细化后每个处理的算法。

5. 设计软件结构

  1. 通常程序中的一个模块完成一个适当的子功能,将模块组织成良好的层次系统,顶层模块调用下层模块以实现程序的完整功能
  2. 软件结构(即由模块组成的层次系统)可以用层次图或结构图来描绘。
  3. 若数据流图细化到适当的层次,则可以直接从数据流图映射出软件结构。

6. 设计数据库

  1. 对于需要使用数据库的应用系统,软件工程师应该在需求分析阶段所确定的系统数据需求的基础上,进一步设计数据库。
  2. 在数据库课中已经详细讲述了设计数据库的方法,本书不再赘述。

7. 制定测试计划

在软件开发的早期阶段考虑测试问题,能促使软件设计人员在设计时注意提高软件的可测试性。
本书第7章将仔细讨论软件测试的目的和设计测试方案的各种技术方法。

8. 书写文档

完成的文档通常有下述几种:

  1. 用系统流程图描绘的系统构成方案,组成系统的物理元素清单,成本/效益分析;对最佳方案的概括描述,精化的数据流图,用层次图或结构图描绘的软件结构,用IPO图或其他工具(例如,PDL语言)简要描述的各个模块的算法,模块间的接口关系,以及需求、功能和模块三者之间的交叉参照关系等等。
  2. 用户手册根据总体设计阶段的结果,修改更正在需求分析阶段产生的初步的用户手册。
  3. 测试计划包括测试策略,测试方案,预期的测试结果,测试进度计划等等。
  4. 详细的实现计划
  5. 数据库设计结果
  6. 审查和复审

最后应该对总体设计的结果进行严格的技术审查,在技术审查通过之后再由使用部门的负责人从管理角度进行复审。
[软件工程] 总体设计(概要设计或初步设计)_第1张图片
[软件工程] 总体设计(概要设计或初步设计)_第2张图片软件设计工作流程

二、设计原理

(一) 模块化

“模块”,又称“构件” 。

  • 过程、函数、子程序和宏等,都可作为模块;面向对象方法学中的对象是模块,对象内的方法(或称为服务)也是模块。模块是构成程序的基本构件。
  • 模块化就是把程序划分成独立命名且可独立访问的模块,每个模块完成一个子功能,把这些模块集成起来构成一个整体,可以完成指定的功能满足用户的需求。
  • 模块化是为了使一个复杂的大型程序能被人的智力所管理,化繁为简、化难为易、化整为零。

设函数C(x)定义问题x的复杂程度,函数E(x)确定解决问题x需要的工作量(时间)。对于两个问题P1和P2,如果C(P1)>C(P2),显然E(P1)>E(P2)。
C(P1+P2)>C(P1)+C(P2)
E(P1+P2)>E(P1)+E(P2)
这就是模块化的根据。
[软件工程] 总体设计(概要设计或初步设计)_第3张图片
[软件工程] 总体设计(概要设计或初步设计)_第4张图片

(二)抽象

  • 抽象就是抽出事物的本质特性而暂时不考虑它们的细节。

  • 处理复杂系统的有效的方法是用层次的方式构造和分析它。一个复杂的动态系统首先可以用一些高级的抽象概念构造和理解,这些高级概念又可以用一些较低级的概念构造和理解,如此进行下去,直至最低层次的具体元素。

  • 任何问题的模块化时,可提出许多抽象的层次。
    在抽象的最高层次使用问题环境的语言,以概括的方式叙述问题的解法;
    较低抽象层次采用更过程化的方法,把面向问题的术语和面向实现的术语结合起来叙述问题的解法;
    最后在最低的抽象层次用可直接实现的方式叙述问题的解法。

  • 软件工程过程的每一步都是对软件解法的抽象层次的一次精化。
    可行性研究阶段,软件作为系统的一个完整部件;
    需求分析期间,软件解法是使用在问题环境内熟悉的方式描述的;
    由总体设计向详细设计过渡时,抽象的程度也就随之减少了;
    最后,当源程序写出来以后,也就达到了抽象的最低层。

  • 逐步求精和模块化的概念,与抽象是紧密相关的。
    软件结构顶层的模块,控制了系统的主要功能并且影响全局;
    在软件结构底层的模块,完成对数据的一个具体处理,用自顶向下由抽象到具体的方式分配控制,简化了软件的设计和实现,提高了软件的可理解性和可测试性,并且使软件更容易维护。

(三)逐步求精

逐步求精是人类解决复杂问题时采用的基本方法,逐步求精可定义为:“为了能集中精力解决主要问题而尽量推迟对问题细节的考虑。”
逐步求精之所以如此重要,是因为人类的认知过程遵守Miller法则:一个人在任何时候都只能把注意力集中在(7±2)个知识块上。
Miller法则是人类智力的基本局限,我们不可能战胜自己的自然本性,只能接受这个事实,承认自身的局限性,并在这个前提下尽我们的最大努力工作。
逐步求精最初是由Niklaus Wirth提出的一种自顶向下的设计策略, Wirth曾说:
“我们对付复杂问题的最重要的办法是抽象,因此,对一个复杂的问题不应该立刻用计算机指令、数字和逻辑符号来表示,而应该用较自然的抽象语句来表示,从而得出抽象程序。抽象程序对抽象的数据进行某些特定的运算并用某些合适的记号(可能是自然语言)来表示。对抽象程序做进一步的分解,并进入下一个抽象层次,这样的精细化过程一直进行下去,直到程序能被计算机接受为止。这时的程序可能是用某种高级语言或机器指令书写的。”
求精要求设计者细化原始陈述,随着每个后续求精(即细化)步骤的完成而提供越来越多的细节。

  • 抽象与求精是一对互补的概念。
  • 抽象使得设计者能够说明过程和数据,同时却忽略低层细节。
  • 求精则帮助设计者在设计过程中逐步揭示出低层细节。
  • 这两个概念都有助于设计者在设计演化过程中创造出完整的设计模型。
    [软件工程] 总体设计(概要设计或初步设计)_第5张图片

(四) 信息隐藏和局部化

如何得到最好的一组模块?

  • 信息隐藏原理指出:设计一个模块,使得包含的信息(过程和数据) 对于不需要这些信息的模块来说,是不能访问的。
  • 局部化是指把一些关系密切的软件元素
  • 物理地放得彼此靠近。
  • 在模块中使用局部数据元素是局部化的一个例子。局部化有助于实现信息隐藏。

(五) 模块独立

模块独立是模块化、抽象、信息隐藏和局部化概念的直接结果。
希望这样设计软件结构,使得每个模块完成一个相对独立的特定子功能,并且和其他模块之间的关系很简单。

模块独立的两条理由:
第一,有效的模块化(即具有独立的模块)的软件比较容易开发。
因为功能简单而且接口可简化,当许多人分工合作时这个优点尤其重要。
第二,独立的模块比较容易测试和维护。
模块独立是设计的关键,而设计又是决定软件质量的关键环节。
模块的独立程度可以由两个定性标准度量,分别称为内聚和耦合。

  • 耦合用于衡量不同模块彼此间互相依赖(连接)的紧密程度;
  • 内聚衡量一个模块内部各个元素彼此结合的紧密程度。
  • 模块独立要求:高内聚、低耦合;
  • 耦合
    耦合是对一个软件结构内不同模块之间互连程度的度量。
    耦合强弱取决于模块间接口的复杂程度,进入或访问一个模块的点,以及通过接口的数据。
    模块间的耦合程度强烈影响系统的可理解性、可测试性、可靠性和可维护性。
    在软件设计中应该追求尽可能松散耦合的系统。
    模块分解的一个目标是使块间联系尽可能小,块间联系的大小可从三个方面衡量:
    [软件工程] 总体设计(概要设计或初步设计)_第6张图片
    [软件工程] 总体设计(概要设计或初步设计)_第7张图片
    (1)内容耦合(content coupling)
    一个模块直接访问另一模块的内部数据。
    一个模块不通过正常入口转到另一模块的内部。
    一个模块有多个入口。
    两个模块有部分代码重迭。
    [软件工程] 总体设计(概要设计或初步设计)_第8张图片
    (2)公共耦合(common coupling)
    若干模块访问一个公共的数据环境,则它们之间的耦合称为公共耦合。公共环境可为全局数据结构、共享的通信区、内存的公共覆盖区等。显然,公共数据区的变化,将影响所有公共耦合模块,严重影响模块的可靠性和可适应性,降低软件的可读性。
    [软件工程] 总体设计(概要设计或初步设计)_第9张图片
    (3)控制耦合(control coupling)
    一个模块传递给另一模块的信息是用于控制该模块内部逻辑的控制信号。
    显然,对被控制模块的任何修改,都会影响控制模块。
    [软件工程] 总体设计(概要设计或初步设计)_第10张图片
    (4)复合耦合(Data Coupling)
    一个模块传送给另一个模块的参数是一个复合的数据结构,例如,包含几个数据单项的记录。

(5)数据耦合(Data Coupling)
若两个模块间通过参数交换信息,而且交换的信息仅仅是数据。数据耦合是松散的耦合,模块之间的独立性比较强。
2. 内聚
内聚标志一个模块内各个元素彼此结合的紧密程度,它是信息隐藏和局部化概念的自然扩展。
理想内聚的模块只做一件事情。
设计时应该力求做到高内聚,通常中等程度的内聚也是可以采用的,而且效果和高内聚相差不多;但是,低内聚很坏,不要使用。
内聚性愈强,模块独立性愈好。
[软件工程] 总体设计(概要设计或初步设计)_第11张图片
偶然内聚:
模块内部各部件之间没有任何关系,仅仅为了满足模块尺寸要求而将一些程序合入一可模块,出现错误时,难以确定位置;
[软件工程] 总体设计(概要设计或初步设计)_第12张图片
逻辑内聚:
这种模块把几种相关的功能组合在一起,每次调用时,由传送给模块的判断参数来确定该模块应执行那种功能。
[软件工程] 总体设计(概要设计或初步设计)_第13张图片
瞬时内聚:
模块包含的任务必须在同一段时间内执行,由于不使用选择参数,逻辑简单,但结合了许多无关任务,错误难以定位。
例如:各种初始化。

通信内聚:
模块中所有的部件都访问同一组数据,几个部件之间有数据关系而无控制关系。
优点:可通过参数选择不同的作用,是一种较理想的内聚。[软件工程] 总体设计(概要设计或初步设计)_第14张图片

顺序内聚:
模块完成多个功能,各个功能都在同一数据结构上操作,每项功能有唯一的入口点。
较好的内聚。
[软件工程] 总体设计(概要设计或初步设计)_第15张图片
功能内聚:
模块内所有部件处理同一组数据,共同完成单一的功能,是最理想的内聚之一。
[软件工程] 总体设计(概要设计或初步设计)_第16张图片

三、启发规则

在长期的软件开发实践中,总结经验,得出了一些启发式规则。
没有基本原理和概念那样普遍适用,在改进软件设计,提高软件质量有积极意义。
 下面介绍几条启发式规则。
  1.改进软件结构提高模块独立性
  2.模块规模应该适中
  3. 深度、宽度、扇出和扇入都应适当
  4. 模块的作用域应该在控制域之内
  5. 力争降低模块接口的复杂程度
  6. 设计单入口单出口的模块
  7. 模块功能应该可以预测

四、描绘软件结构的图形工具

(一) 层次图和HIPO图

层次图用来描绘软件的层次结构。
[软件工程] 总体设计(概要设计或初步设计)_第17张图片

(二)结构图

结构图也是描绘软件结构的图形工具。
一个方框代表一个模块,框内注明模块的名字或主要功能;方框之间的箭头(或直线)表示模块的调用关系。
尾部是空心圆表示传递的是数据,实心圆表示传递的是控制信息。
[软件工程] 总体设计(概要设计或初步设计)_第18张图片

(三)结构图

有一些附加的符号,可以表示模块的选择调用或循环调用。
如左图表示当模块M中某个判定为真时调用模块A,为假时调用模块B。如右图表示模块M循环调用模块A、B和C。

五、 面向数据流的设计方法

面向数据流的设计方法的目标是给出设计软件结构的一个系统化的途径。
因为任何软件系统都可以用数据流图表示,所以面向数据流的设计方法理论上可以设计任何软件的结构。
通常所说的结构化设计方法(简称SD方法),也就是基于数据流的设计方法。

(一)概念

面向数据流的设计方法把信息流映射成软件结构,信息流的类型决定了映射的方法。信息流有下述两种类型。

  1. 变换流
    [软件工程] 总体设计(概要设计或初步设计)_第19张图片
  2. 事务流
    如图所示,数据流是“以事务为中心的”,即数据沿输入通路到达一个处理T,根据输入数据的类型选出一个来执行。这类数据流应该划为一类特殊的数据流,称为事务流。
    [软件工程] 总体设计(概要设计或初步设计)_第20张图片
    如图处理T称为事务中心,它完成下述任务:
    (1) 接收输入数据(输入数据又称为事务);
    (2) 分析每个事务以确定它的类型;
    (3) 根据事务类型选取一条活动通路。

3 设计过程
基于数据流方法的设计过程
[软件工程] 总体设计(概要设计或初步设计)_第21张图片

(二) 变换分析

变换分析把具有变换流特点的数据流图按预先确定的模式映射成软件结构。
 
中心变换型(transform center)— 变换分析
其特点是:DFD图可以明显分为“输入-处理-输出”三部分。
[软件工程] 总体设计(概要设计或初步设计)_第22张图片
 事务处理型(transaction)— 事务分析
  这类数据流图可看成是对一个数据经过某种加工后,按加工的结果选择一个输出数据流继续执行的处理。
[软件工程] 总体设计(概要设计或初步设计)_第23张图片

(三)事务分析技术

① 确定流界:首先从数据流图中找出事务流、事务处理中心和事务路径。
② 进行一级分析,设计上层模块:对事务中心应设计“事物控制”模块;对事物流应设计“接受事物”模块;对事务路径,应设计“发送控制”模块。
③ 进行二级分解,设计中下层模块:接受分支,用类似于转换处理型数据流图中对输入数据流的方法设计中下层。对于发送分支,在发送控制模块下为每条事务路径设计一个事务处理模块,这一层称为事务层。
[软件工程] 总体设计(概要设计或初步设计)_第24张图片

(四) 设计优化

设计优化应力求做到在有效的模块化的前提下使用最少量的模块,以及在能够满足信息要求的前提下使用最简单的数据结构。
对于时间是决定性因素的场合,下述方法对软件进行优化是合理的:

  • (1)在不考虑时间因素的前提下开发并精化软件结构;

  • (2)在详细设计阶段选出最耗费时间的那些模块,仔细地设计它们的处理过程(算法),以求提高效率;

  • (3) 使用高级程序设计语言编写程序;

  • (4) 在软件中孤立出那些大量占用处理机资源的模块;

  • (5) 必要时重新设计或用依赖于机器的语言重写上述大量占用资源的模块的代码,以求提高效率。

上述优化方法遵守了一句格言:“先使它能工作,然后再使它快起来。”

你可能感兴趣的:([软件工程],总体设计(概要设计或初步设计))