软件工程导论(中)

笔记参考:广州大学软件工程教学

软件工程是软件工程专业的一门重要学科,掌握好软件工程原理是开发软件的重要基础知识。本博客对软件工程导论进行了详细的讲解,以方便理解。

目录

  • 六. 软件设计概论
    • 6.1 软件设计的概念
      • 6.1.1 软件设计模型
      • 6.1.2 设计模型的质量要素
    • 6.2 软件设计的基本原则
      • 6.2.1 抽象与逐步求精
      • 6.2.2 模块化
      • 6.2.3 信息隐藏
      • 6.2.4 关注点分离
    • 6.3 软件设计活动
      • 6.3.1 软件设计活动概念
      • 6.3.3 设计过程模型的裁剪
  • 七. 软件体系结构的设计
    • 7.1 软件体系结构的概念
      • 7.1.1 何谓体系结构
      • 7.1.2 体系结构视图
    • 7.2 体系结构的表示
      • 7.2.1 包图
      • 7.2.2 构件图
      • 7.2.3 部署图
        • 7.2.3.1 描述性部署图
        • 7.2.3.2 实例性部署图
      • 7.2.4 对象图
    • 7.3 体系结构设计的过程模型
    • 7.4 体系结构设计模式
      • 7.4.1 何谓设计模式
      • 7.4.2 通用的体系结构模式
    • 7.5 概念设计
      • 7.5.1 关键需求辨识
      • 7.5.2 体系结构初创
    • 7.6 体系结构的精化
      • 7.6.1 逻辑视图的体系结构精化
      • 7.6.2 开发视图体系结构设计
      • 7.6.3 物理视图体系结构设计
      • 7.6.4 运行视图体系结构设计
      • 7.6.5 数据视图体系结构的设计
    • 7.7 软件复用
      • 7.7.1 软件复用概述
      • 7.7.2 构件创立
    • 7.8 体系结构验证
  • 八. 人机交互设计
  • 九、软件详细设计
    • 9.1 用例设计
  • 9.2 子系统的设计
    • 9.3 构件的设计
      • 9.3.1 为复用设计构件
      • 9.3.2 设计构件的定制机制
      • 9.3.3 设计构件的组装机制
    • 9.5 类设计
      • 9.5.1 精细化类间关系
      • 9.5.2 精化属性和操作
      • 9.5.3 数据模型的设计
    • 9.6 设计整合与验证
  • 十、软件实现
    • 10.1 编程标准
    • 10.2 软件调试
  • 十一、结构化的软件开发
    • 11.1 面向数据流的分析方法

六. 软件设计概论

6.1 软件设计的概念

软件设计:针对需求工程给出的软件需求模型,综合考虑各种制约因素,探求切实可行的软件解决方案并最终给出方案的逻辑表示,这种表示又被称为设计模型

软件设计的制约因素主要来自于资源技术两方面。
资源制约:在软件开发过程中可以获取的时间,人力,财力,开发辅助工具等
技术制约:待开发目标软件系统可以使用的技术平台

软件设计是需求模型和实现代码之间的“桥梁”,是达成软件质量目标的关键性阶段。

6.1.1 软件设计模型

设计元素:出现在设计模型中的模块,这些模块的表现形式包括子系统,构建和类

  • 子系统:完成一组逻辑上相互关联的系统功能的模块的集合,他应该作为一个整体进行设计,构造和部署,因为其功能相对独立于其他软件模块的功能
    • 子系统与软件系统的其余部分的协作主要通过接口来完成,子系统内部的模块及其协作应尽量被子系统的接口隐藏。
  • 构件:可执行软件系统中一个可分离、可独立部署的部分
    • 构件的封装性比子系统更严格,他仅仅通过接口对外提供服务,内部实现细节完全隐藏,他的设计更专注于易复用性,易组装性

设计模型是软件问题解决方案的逻辑表示

设计模型的内容应该包括:

  • 宏观说明目标软件系统的整体结构,这种宏观的软件结构在软件工程中称为“体系结构”
    • 从高层抽象的角度刻画组成目标软件系统的模块以及他们之间的逻辑关联和协作关系
  • 用户界面的设计——界面类
  • 必须说明用户界面模型和体系结构模型中设计元素如何协同工作以实现每项软件需求
  • 数据存储也是设计模型中不可缺失的环节
  • 如果体系结构中的子系统或构件规模较大,需要对其内部进行展开——子系统设计模型和构件设计模型
  • 类设计模型

综上,典型的软件设计模型一般包含体系结构模型,用户界面模型,用例设计模型,数据模型,子系统/构件/类设计模型

就像我们搭房子要先搭框架,然后再细化房子里面的内容。

6.1.2 设计模型的质量要素

软件设计的目标是构建高质量的设计模型。
设计模型的质量要素:正确性(一致性和可行性)、充分性、优化性和简单性

6.2 软件设计的基本原则

软件设计原则包含:
抽象与逐步求精、强内聚及松耦合、信息隐藏及关注点分离

6.2.1 抽象与逐步求精

抽象:集中在某一层次上考虑问题,暂时忽略那些低层次的细节
抽象是管理、控制问题复杂性的基本策略。
软件设计的抽象原则是指:软件设计一般要自顶向下经历一系列抽象级别从高到低的设计阶段,后续阶段会在前一阶段的基础上引入更接近于软件实现的设计元素,这一过程称为“逐步求精”。

6.2.2 模块化

将软件系统划分为若干相对独立的部件(模块),所有模块组装后可获得满足问题需要的软件解
但是,并不是意味着我们要不断的将软件系统划分模块,因为总耗费并不是随着划分的模块越多而减少的
软件工程导论(中)_第1张图片

为了解决模块化分解相关的难题,引入模块内聚度和耦合度两个概念

内聚度
内聚度表示一个模块内部各成分彼此关联的程度
内聚度的表现形式:

  • 偶然性内聚
    • 模块各成分为完成一组功能而组合在一起,他们互相之间即使有关系,也很松散
  • 逻辑性的内聚
    • 模块完成多项功能,这些功能在逻辑上具有某种相关性
  • 时间性内聚
    • 模块完成的任务必须在同一个时间段内执行
  • 过程性内聚
    • 在逻辑性内聚的基础上,进一步要求模块内各功能必须按特定的次序执行
  • 通信性内聚
    • 模块中各成分对数据结构的同一区域进行操作,以达到通信的目的
  • 顺序性内聚
    • 模块内各处理均与同一功能相关,且这些处理必须依序执行
  • 功能性内聚
    • 模块内各成分协同完成单一功能

前三种内聚度较低,4、5内聚度居中,后面两种内聚度最高
模块的内聚度越高越好

耦合度
耦合度是指软件结构中多个模块之间的关联程度。耦合的强弱取决于模块间接口的复杂性,通过接口传递的数据量的大小及复杂性等。

在设计软件时应追求尽可能松散耦合的系统结构

模块间的耦合度直接影响软件系统的可理解性、可测试性、可维护性和可靠性

模块间的耦合度从低到高有五种表现形式:

  • 非直接耦合:两模块中任意一个都不依赖于另一个而独立工作
  • 数据耦合:如果两个模块通过参数的交换信息,这些信息仅参与计算而不影响模块的功能或执行路径
  • 控制耦合:模块间交换的参数因为取值不同而导致模块功能或执行路径的变化
  • 外部耦合:当若干个模块与同一外部设备或外部环境相关联
  • 公共耦合:当若干模块通过公共的数据环境相互作用时。公共数据环境的种类包括全局变量,被多个模块共用的内存区或存储介质上的文件等
  • 内容耦合:两模块的业务逻辑处理线索相互交织,或他们交互的复杂度高于前面的耦合形式

软件设计时应尽量使用非直接耦合和数据耦合,减少控制耦合,限制外部耦合和公共耦合,杜绝内容耦合

强内聚、松耦合原则
是软件设计领域最重要,最经典的原则之一

6.2.3 信息隐藏

模块应设计得使其所含信息(过程和数据)对于那些不需要这些信息的模块不可访问,模块之间仅交换那些为完成系统功能必须交换的信息
好处:支持模块的并行开发,减少测试和后期维护工作量

6.2.4 关注点分离

关注点是指问题求解者针对概念、任务或目标的某个部分或侧面的聚焦
抽象与逐步求精,模块化都是关注点分离原则的具体应用:前者分离“结构”和“细节”,后者分离指责型和功能型关注点
其实就是一个分而治之的原则

可以沿 “职责划分”、“结构-细节”及“通用-专用” 三个维度来分离关注点

软件工程导论(中)_第2张图片

6.3 软件设计活动

6.3.1 软件设计活动概念

完整的软件设计过程的活动:

  • 设计策划
  • 体系结构的设计
    • 软件的体系结构是指,软件系统中主干模块的组织形式,包括这些模块的职责分派,他们之间的接口定义,协作关系及协作行为
  • 人机交互设计
  • 详细设计
  • 设计整合与验证
  • 总结
    在这里插入图片描述

6.3.3 设计过程模型的裁剪

软件设计过程模型的裁剪方法与需求工程过程模型的裁剪方法相似

七. 软件体系结构的设计

7.1 软件体系结构的概念

软件体系结构,也称架构,从高层抽象的角度刻画组成目标软件系统的设计元素(包括子系统,构件及类)以及他们之间的逻辑关系。软件体系结构是构成后续的详细设计和软件实现的主要工作基础。

在一个设计模型中可以存在一系列抽象级别不同的体系结构模型

抽象级别越低,模型中子系统或构件的粒度越小,软件实现的细节越多。
自顶向下,逐步精化是一种广泛采用,行之有效的设计原则。

体系结构设计的任务是,建立满足软件需求的软件体系结构。
体系结构既要明确定义软件各子系统,构件、关系类的职责划分及协作关系,也要描绘他们在物理运行环境下的部署模型。
体系结构还必须针对软件系统全局性、基础性的技术问题给出技术解决方案,这种方案构成目标软件系统的技术基础设施。

体系结构设计是从what(需求)迈向how(设计)的第一步,选项很多,迷茫很多。

7.1.1 何谓体系结构

软件体系结构包括三大要素:

  • 组件:软件系统的一个组成单元
  • 连接件:组件之间的连接和交互关系
  • 约束:组件中的元素应该满足的条件,以及组件经过连接件组成更大的模块时应满足的条件

软件体系结构涉及的约束的一些例子:

  • 位于叫高层的软件元素可以向低层元素发出服务请求,低层元素完成计算后向高层元素发送服务应答,反之不行。
  • 每个软件元素根据其职责位于最恰当的一个层次当中,不可错置(如核心层不能包含界面呈现和界面输入职责,也不能直接与物理设备层交互)
  • 每个层次都可替换,即,一个层次可以被能实现同样对外服务接口的层次替代

软件需求和体系结构设计之间的关系:
体系结构是以软件需求的实现为目标的软件设计为蓝图,软件需求是体系结构设计的基础和驱动因素。

7.1.2 体系结构视图

针对大中型软件项目,软件系统的规模和复杂性都会给体系结构设计造成许多困扰,任何从单一视角的软件体系结构视图都难免遗漏和片面。通常认为,一个软件体系结构设计应该包含以下视图:

  • 逻辑视图:体系结构中各软件模块的逻辑功能划分(或称职责划分),以及基于这种划分的协作性行为
  • 开发视图:软件源代码的程序分包及目录结构,采用的类库,中间件或框架,他们与逻辑视图中各模块之间的映射
  • 物理视图:物理部署
  • 运行视图:进程以及线程的划分
  • 数据视图:数据传递,划分等等

7.2 体系结构的表示

用于表达体系结构的逻辑视图的UML图形机制主要是包图和构件图,有时还辅以类图
开发视图的表示可能会用到包图
物理视图用到部署图
因为运行视图涉及到并发,同步以及软件运行过程中的瞬时快照,所以他表示为活动图和对象图
数据视图一般表示为类图或者实体-活动图,但是一般用类图就可以表示

7.2.1 包图

包图刻画包之间的构成和依赖关系。其中,包是UML模型的一种组织单元,他可以包含一组具有逻辑关联的UML模型元素(例如用例、类等),模型图(例如用例图、类图、交互图、状态图、活动图等),以及其他的包。
包在模型管理过程中是配置管理的基本单元,同时也为访问控制提供基本手段。
在设计和实现阶段,包图可以用于描述软件系统的高层结构。
软件工程导论(中)_第3张图片

(一)包及包间依赖
从四个角度理解包:

  • 作为软件模型的组织单元。对于一个大型的软件系统,UNL模型图可能十分庞大、复杂。因此,有必要将系统划分为不同的包,在每个包中构建各类模型图。
  • 作为模型管理的基本单元
  • 作为系统高层结构中的组成元素。对于大型的软件设计而言,可以逐级细分的包才是软件高层结构中恰当的组成元素。
  • 作为访问控制的基本手段

UML以包为基准建立了可见性原则:
包中可见性定义为public的元素可以在模型的任何地方被引用
包的可见性定位为private的元素仅在该元素所在的(最内层)包中可见,其他地方不能引用。

即便建模者不显示的定义包,UML缺省地认为所有无明显归属的元素属于一个隐含的,匿名的顶层包,他是“属于”关系树的根节点。
两个包之间的依赖关系是他们各自包含的模型元素之间的依赖关系在较高抽象层次上的汇总。包的依赖关系是内部模型依赖关系的一个体现。
包间依赖仅仅说明分属两个包的某些元素之间存在依赖关系,而非所有元素之间都存在依赖关系。
包的划分必须遵循强内聚,松耦合原则

(二)包图
包图是类图的变种。
包图仅体现包之间的两种关系:构成和依赖
如果包图的每个包中仅包含类,就称这类包图为类包图
如果包图的每个包中仅包含用例,就称这类包图为用例包图

(三)布局规则

  • 对类包图采用垂直分层布局,沿垂直方向绘制依赖关系边,位于同一层次的包水平对齐,最面向用户的包位于顶层,面向系统内部后台处理的包位于底层。
  • 用例包图采用水平布局,主动执行者,被动执行者分置于图的左右侧

7.2.2 构件图

构件是可执行软件系统中的某个可分离的物理模块,他具有精确定义的对外接口,并且外界只能通过接口来访问他。构件是可分离的,他通常表现为一个或数个可独立部署的执行码文件。
构件一般具有较好的可复用性

构件图
构件图描述软件系统中的构件以及构件之间的构成关系和依赖关系。
软件工程导论(中)_第4张图片

(一)构件及其表示

  • 接口是一组操作和/或属性说明(不含操作实现),他用做服务提供方和使用方之间的协议。接口由类和构件实现。
  • 构件最关键的特征是对外提供供给接口,以及需求接口
  • 构件的实现与接口是分离的,也是隐藏的。
  • 只要构件的两种实现遵循相同的接口定义,那么他们就一定可自由替换的。
  • 构件的表示图元仅出示构件的名字和接口
  • 端口包含接口

软件工程导论(中)_第5张图片

(三)构件定义图

  • 构件定义图描述一个构件的内部结构。他可以包含多个子构件,每个子构件的需求接口要么由另一子构件的供给接口负责实现,要么经由父构件的需求接口请求外部支援,这样才能构成构件的完整实现。
  • 子构件端口与父构件端口之间的有向边称为委托连接器

7.2.3 部署图

部署图表示软件系统的执行工件在运行环境中的分布情况。
两种部署图:逻辑层面的描述性部署图,物理层面的实例性部署图
描述性部署图描述软件的逻辑布局
实例性部署图在描述性部署图的基础上针对具体的运行环境和特定的系统配置描述软件系统的物理部署情况。

软件工程导论(中)_第6张图片
软件工程导论(中)_第7张图片

7.2.3.1 描述性部署图

描述性部署图的四类节点:

  • 结点:表示软件运行环境中的一组计算资源,如:客户端计算机、Web服务器端、应用服务器、数据库服务器等。
  • 工件:以构造型< < artifact > >标识。工件位于结点图元之内,表示该工件部署相应结点。
  • 构件
    • 位于结点内的构件表示该构件部署于相应结点
    • 位于结点外的构件用来指明工件与构件之间的依赖关系
    • 不需要将所有的构件都引入部署图,仅显示相关的、重要的构件即可。
  • 与用例有关的执行者

描述性部署图有四种边

  • 结点之间的通信关联:表示两个结点间的通信连接
    • 例如可以标注结点之间的数量对应关系
  • 工件之间的依赖关系
  • 工件和构件之间的依赖关系:表示工件具体实现了构件,在依赖关系之上要标注构造型< < manifest > >
  • 用例执行者和工件之间的依赖关系

7.2.3.2 实例性部署图

实例性部署图和描述性部署图之间的关系可类比成对象图和类图之间的关系

7.2.4 对象图

对象图是软件系统中某些对象在运行过程中的瞬时快照
节点表示对象,边表示对象之间的链接
软件工程导论(中)_第8张图片

可以将对象图理解为类图在软件系统运行过程中某个时刻点上或某一时间段内的实例化样本。

7.3 体系结构设计的过程模型

体系结构的主要任务是建立满足软件需求的软件高层结构,在这种结构中设置软件系统中的所有重要模块并明确定义这些部件的职责划分和协作关系。
体系结构雏形是指软件体系结构逻辑视图的初始形态。

概念设计(雏形)-》体系结构精化-》体系结构验证
在这里插入图片描述

7.4 体系结构设计模式

7.4.1 何谓设计模式

设计模式是指以设计复用为目的,采用一种良好定义的、正规的、一致的方式记录的软件设计经验。
每条模式关注在一般或特定设计环境中可能重复出现的设计问题,并给出经过充分实践考验的软件解决方案。

一种设计模式包含以下内容:

  • 设计模式名称
  • 问题
  • 施用条件
  • 解决方案
  • 效果
  • 实例代码
  • 关联模式

7.4.2 通用的体系结构模式

体系结构模式是专门针对体系结构设计问题的设计模式,是软件体系结构设计的经验结晶。

分层模式
该模式将软件系统按照抽象级别逐次递增或递减顺序划分为若干层,每层由一些抽象级别相同的组件组成。
一般而言,顶层直接面向用户提供软件系统的交互界面,底层则直接负责提供基础性、公共性的技术服务,他比较接近于硬件计算环境,操作系统或数据库管理系统,中间层的抽象级别介于两者之间

层次间的连接有两种形态:

  • 高层构件向底层构件发出服务请求,底层构件在计算完成后向请求者发送服务应答。
  • 在这个过程中,底层构件可能向更低层构件发出抽象级别更低、粒度更细的服务请求。

每个层次对上层服务接口的两种组织方式

  • 层次中的每个提供服务的构件公开其接口
  • 将这些接口封装于层次内部,每个层次提供统一的、整合的服务接口

前一种方式对上层服务请求者更直接,服务提供者所在层次的透明度也高
后一种方式降低了两个层次之间的耦合度。

软件工程导论(中)_第9张图片

管道与过滤器模式
管道与过滤器模式将软件系统的功能实现为一系列处理步骤,每个步骤封装在一个过滤器构件中。
该模式仅适用采用批量处理方式的软件系统,不适合交互式,事件驱动式系统
软件工程导论(中)_第10张图片

黑板模式
黑板模式将软件系统划分为黑板、知识源和控制器
黑板模式适用于没有确定的求解方法的复杂问题。
软件工程导论(中)_第11张图片

7.5 概念设计

概念设计的主要目标是根据关键需求确定初始的软件体系结构雏形。

7.5.1 关键需求辨识

关键需求包括关键的功能需求项和关键的非功能需求项

辨识关键功能需求项的主要方法

  • 确定核心或基础性功能
  • 确定为实现对外接口所必须的支持功能
  • 标识实现难度较大,实现风险较高的功能
  • 确定最能体现待开发的软件特色的功能需求
  • 确定前述类别没有覆盖,但对用户满意度影响甚巨的功能需求
  • 剔除对体系结构塑形无贡献的功能需求项

7.5.2 体系结构初创

体系结构初创的任务是建立初始的软件体系结构雏形,他属于软件体系结构的逻辑视图,与具体的软件实现技术无关。
建立体系结构雏形的依据主要是前述的关键需求集,注意,建立雏形还需要考虑运行环境。

例子:软件工程导论(中)_第12张图片

7.6 体系结构的精化

体系结构的精化目标是将概念体系结构精化成全面的、设计适度的软件体系结构
软件体系结构一般包含逻辑、运行、数据、物理开发五种视图
重点是逻辑视图的精化

7.6.1 逻辑视图的体系结构精化

概念体系结构与精化后的逻辑体系结构的区别:

  • 出现在概念体系结构中的模块仅仅代表逻辑职责,而精化后体系结构中的模块不仅代表逻辑职责,还必须有明确的接口定义
  • 概念体系结构中的模块划分主要职责是逻辑分组,精化体系结构中的模块划分必须考虑可用的设计资产(如开源构件、开源框架),技术支撑设施,分布部署,开发技能的专业化分工甚至并行开发等因素。
  • 概念体系结构与精化后的逻辑结构体系设计的最重要的区别是,后者必须具备设计充分性(非关键的需求也要囊括进来)

设计过程:

  • 搜索并选取可用的设计资产
  • 设计技术支撑设施
  • 确定设计元素
  • 整合设计元素

与概念体系结构一样,仍采用扩充的UML包图表示精化后的逻辑体系结构
在之前的基础上,添加以下扩充:
允许在包图中出现构件、类和接口,允许在包图中表示子系统和构件的服务接口,采用构造型:
<< sub system > >
<< external sub system> >
<< external component > >
软件工程导论(中)_第13张图片

设计技术支撑设施
技术支撑设施应该为多个用例的软件实现提供技术服务,所以,他应该成为整个目标软件系统中全局性的公共技术平台。
当用户需求发生变化时,技术支撑设施应该具有良好的稳定性。
如果目标软件系统的顶层结构采用分层方式,那么技术支撑设施应该位于较低层次。

数据持久存储服务
在目标软件系统结束一次运行之后,其产生的部分数据能够存留于系统的存储介质中,以供本软件下次运行时使用,或者其他软件系统使用。数据存取一般通过数据管理系统实现
软件工程导论(中)_第14张图片

确立设计元素
设计元素包括子系统、构件、设计类三种
确定设计元素的接口和相互协作关系,不需要给出设计元素的内部结构和实现途径,此项工作留给子系统设计,构件设计和类设计再进行。

7.6.2 开发视图体系结构设计

开发视图体系结构主要关注软件源代码文件(含配置文件)的程序分包及目录结构,编译后生成的目标文件包,他们之间的关系以及他们与逻辑视图中各模块之间的映射关系。

开发视图体系结构应该细化至可以支持详细设计和软件实现的并行开展

7.6.3 物理视图体系结构设计

软件体系结构的物理视图负责展示软件中子系统、构件部署到哪些计算结点上运行,以及这些结点之间的网络连接方式。反映了软件系统的网络运行环境和物理分布状况。
软件工程导论(中)_第15张图片

7.6.4 运行视图体系结构设计

运行视图体系结构主要关注目标软件的并行执行。如果不准备在目标软件中引入并行处理,就不必考虑运行视图体系结构的设计。

7.6.5 数据视图体系结构的设计

主要关注持久数据在宏观层面上存储组织方式,必要时还需考虑数据的传递,备份,恢复和同步方案。

7.7 软件复用

7.7.1 软件复用概述

多次不同的软件开发过程中重复使用相同或相似软件元素的过程。软件元素包括源程序模块,目标代码模块,各类文档,测试用例甚至领域知识等。通常将这些可复用的软件元素称为软部件,为了便于复用,通常将可复用的软部件组成为软部件库。目前常见的软部件为类和构件,他们对应的软部件库也就相应的称为类库和构件库

横向复用是指复用面向不同应用领域中软部件,例如数据结构,分类算法,人机界面控件等。标准函数库即是一种典型的,原始横向复用机制。
纵向复用是指一类具有较多公共性的应用领域之间进行软部件复用。纵向复用的关键点在于领域分析:根据应用领域的特征及相似预测软部件的可复用性。

针对采用面向对象方法开发和基于类库的软件复用方法的软件项目,可以采用继承或代理方法来复用类库中的类。

7.7.2 构件创立

在横向复用的情况下,必须确保构件具有跨越多个差异较大的应用领域的可复用价值。
在纵向复用情况下,必须根据领域分析的成果创立构件。
由于纵向复用的潜力远大于横向复用,所以他是构建创立过程中的首要活动。

领域分析
从软件工程的观点看,领域就是向目标软件系统提出应用需求的问题及背景知识。
领域分析的主要任务是,针对单一或一族相似的领域,以软件复用为目标,探寻并挖掘领域或领域族中能够为多个目标软件系统共用的软构件。

7.8 体系结构验证

检查前面获得的软件体系结构是否足以支撑所有软件需求项的实现,是否还有进一步优化的空间

八. 人机交互设计

以用户为中心的设计
屏幕:窗口,对话框,网页
屏幕之间存在页面跳转,称为“界面流”

用户界面设计过程主要活动有:

  • 用户分析,任务分析及建模
  • 概念设计
  • 界面流设计
  • 界面精化

九、软件详细设计

详细设计是软件设计过程的最后环节。
在将设计模型提交给软件编程人员展开软件实现之前,有必要将用例设计,子系统设计,构件设计,类设计,数据模型设计的成果进行整合和必要的优化, 并再次对其进行验证,研究其是否足以支撑所有软件需求项的实现,是否还有进一步优化的空间,是否存在设计不充分的地方。

9.1 用例设计

  • 完整的实现每个用例要求的业务处理功能和交互动作序列。
  • 通过详细考查每个元素与其协作者之间的协作关系,以求更精确的定义这些设计元素,例如补齐必要的细节,调整接口定义等

用例设计的子活动归纳

  • 设计用例实现方案
  • 导出设计类图
    • 设计类图中的节点为各种设计元素,包括子系统,构件和通常的UML类
    • 对UML类图稍作扩充以表示详细设计类图,允许在类图中出现子系统和构件,他们的类别可以采用不同UML构造或不同的图元符号来表示
  • 整合并优化用例实现方案
    • 将具有相同或相似功能的多个设计元素整个为一个
    • 将具有相同或相似功能的多个操作整合为一个
    • 采用继承或代理机制对设计元素中的公共操作进行抽象
    • 确保所有用例实现方案在同一软件系统中和谐共存,无逻辑冲突
    • 根据上述调整修改交互图和设计类图

9.2 子系统的设计

子系统设计的任务是,确定子系统内部的结构,即,设置包含于其中的,粒度更小的子系统,构件和设计类,明确他们之间的协作关系,确保他们能够协同实现体系结构中该子系统的服务提供接口所规定的全部功能和行为。

9.3 构件的设计

构件的任务是,为实现构件的服务提供接口中规定的职责而在其内部设置子构件和类,明确他们的职责,定义对外接口,确定他们之间的协作关系。

9.3.1 为复用设计构件

构件的详细设计必须确保接口与实现相分离。
软件设计师必须分析当前以及将来可能的多种应用场景中对构件的功能需求的相同点和不同点,采取以下方法来提高构件的可复用性:

  • 分离相同点和不同点,将相同点实现为构件
  • 以参数化手段从不同点中抽取出公共部分,通过构件的不同配置覆盖不同点。
  • 将相同点抽象为框架,其中的不同点被定义为框架中的抽象服务。

9.3.2 设计构件的定制机制

构件的定制机制是提高构件的灵活性和可复用性的主要手段之一。

  • 最简单的定制机制就是将构件接口中定义的对外服务参数化,构件使用者通过使用不同的实参值来定制自己需要的构件服务。
  • 另一种构件定制的方法是,以构件为单位定义配置信息,通过配置项的具体取值的不同来实现构件功能的定制。
  • 当设计者希望通过一组参数来影响构件接口定义中的多个对外服务时,此种定义机制优于前述的针对逐个服务的参数化机制。
  • 可以采用基于继承和委托的定制机制

9.3.3 设计构件的组装机制

构件通常基于执行码进行组装

  • 最简单的构件组装是基于构建描述文档的组装,即,构件设计师在每个构件上附加一个描述性文档。
  • 该文档可以采用(结构化)自然语言,也可以采用XML来描述。
  • 使用者通过该文档来了解构件服务的使用方法(包括定制方法)和约束条件,或者,支持构件组装的软件开发环境读取并向构件使用者展示该文档所描述的构件接口以及使用方法。
  • 由构件使用者以手工方式完成构件组装

上述方法有两个明显的缺陷:当构件接口发生变化时,接口描述文件必须相应的改变,因人为错误可能直接导致描述文件与实际构件接口不一致。
自描述接口可以解决上面的问题。其基本思想是,支持构件组装的软件开发环境或构件的运行平台自动从构件的执行码中综合出构件的接口定义,在自描述接口机制的支持下,构件组装有两种途径:静态组装和动态组装。

9.5 类设计

对体系结构中出现的关键设计类,以及界面设计模型,子系统设计模型和构件设计模型中出现的类进行细化设计,以使他们足够精细,能够直接提交给软件构造阶段进行编码实现。

9.5.1 精细化类间关系

  • 确定类间连接关系:类之间关系的语义强度从高到底依次是:继承、组合、聚合,(普通)关联,依赖。按照“强内聚,松耦合”的原则,应该尽量采用语义连接强度较小的关系
    • 此外,可以通过类间连接关系在软件系统运行时发挥的作用----消息传递通道----的视角来选择最合用的连接关系
  • 确定类间连接关系的方向和多重性
    • 对于UML的关联关系,设计师要仔细推敲双向关联的必要性,尽量关联单向化,因为单向化更简单,实现代价更小
  • 优化类间连接关系

9.5.2 精化属性和操作

为了使类图精细化至足够的程度以供软件实现工程师展开编程实现,软件设计师必须详细研究所有的设计类的属性和操作,并完成以下任务:

  • 细化属性和操作的内容
  • 确定属性和操作的作用范围
  • 添加必要的属性或操作
  • 明确标示静态的属性和操作

9.5.3 数据模型的设计

数据模型设计的任务是,确定设计模型中需要持久保存的数据条目,基于数据模型设计这些数据条目的组织方式,必要时还需设计特定于本软件项目采用的数据库管理系统的优化机制,以提高持久数据操作的性能。

9.6 设计整合与验证

设计整合的任务是,汇总迄今获得的所有设计模型,包括体系结构模型,界面设计模型,用例设计模型,子系统/构件/类设计模型,数据模型,在全局范围内检查并消除他们之间的不一致性,剔除冗余性,最终形成设计规约
设计验证的任务是,基于设计规约,重新审视所有软件需求项(包括功能需求项–用例,以及非功能需求项)的实现方案,研究如何化解迄今标识出来的所有重要的全局风险,在此过程中验证详细设计的正确性,优化性和设计充分性

十、软件实现

软件实现是指,通过程序设计及编码的过程,把软件详细设计映照为计算机可以“理解”并最终可运行的代码,它涉及编写代码、单元测试、集成测试、调试、确认等多项活动,是一个迭代的过程,他除了要求编写的代码完全符合软件设计确定的功能,还需要控制和降低程序复杂性,增强程序的可维护性

软件实现过程
软件工程导论(中)_第16张图片

10.1 编程标准

  • 编制易于修改、维护的代码
  • 编制易于测试的代码
  • 必须把编程与编文档的工作统一起来
  • 编程中要采用统一的标准和约定,降低程序的复杂性
  • 限定每一层的副作用,减低耦合性
  • 尽可能复用

10.2 软件调试

  • 识别问题
  • 收集信息
  • 假设缺陷原因
    • 内存资源泄露
    • 逻辑错误(最难的错误)
    • 访问越界
    • 条件错误
    • 指针错误
    • 分配/释放错误
    • 多线程错误
    • 存储错误
    • 集成错误
    • 转换错误
    • 版本和复用错误
  • 追加测试

调试的方法

  • 原始类:通过计算机找错
  • 回溯类:从出现缺陷征兆处开始,人工地沿控制流程往回追踪,直至发现缺陷根源。
  • 排除类:基于归纳和演绎原理,采用“分治”的概念,首先收集与缺陷出现有关的所有数据,假想一个缺陷原因,用这些数据证明或反驳他,或者一次列出所有可能的原因,通过测试一一排除。只要某次测试结果说明某种假设已经出现端倪,则立即精化数据,乘胜追击。

十一、结构化的软件开发

11.1 面向数据流的分析方法

可以认为,一个基于计算机的信息处理系统由数据流和一系列的转换构成,即IPO模型
软件系统通过一系列的转换(也称“加工”)将输入数据变换为输出数据
数据流图就是用来刻画数据流和转换信息系统建模技术,任何软件系统都可以用数据流图表示。
数据流图用简单的图形记号分别表示数据源,数据流,转换以及外部实体。

软件工程导论(中)_第17张图片
软件工程导论(中)_第18张图片

数据流
在这里插入图片描述

  • 数据流表示数据和数据的流向,这里的数据可以是单一的数据项,更多的是由数据项组成的数据结构
  • 数据流命名应该直观反映数据流的含义
  • 数据流可以从加工流向加工,也可以在加工与数据存储或外部项之间流动,两个加工之间可以有多股数据流

数据流与数据加工之间的关系
软件工程导论(中)_第19张图片

加工
在这里插入图片描述

  • 又称数据加工或数据处理
  • 指对数据的逻辑处理,也就是对数据变换功能,即对数据进行的操作
  • 别名:功能,处理过程,数据加工
  • 当有两部分时,一般上部是编号或编号+名称,下部是名称或功能简述
  • 对数据流图的加工进行编号,要能体现这个加工在层次分解中的位置
  • 数据流图是一种层次结构鲜明的图,层次化的加工编号能够很好地体现加工所处的层次
    软件工程导论(中)_第20张图片

数据存储
软件工程导论(中)_第21张图片

  • 数据存储是指某种数据保存后的逻辑统称,不是指保存数据的物理地点或物理介质
  • 数据存储一般仅属于某一层或几层,又称局部文件
  • 数据存储除了要命名外,也可编号,尤其数据存储较多时,当有编号和名称时用单开口的矩形框
  • 标号建议D开头
  • 命名与数据流,加工类似,能够体现核心内容
    在这里插入图片描述

数据存储的流入与流出

  • 数据存储必须有数据流
    • 流入的数据流:将处理后的数据写入或更新到数据存储中
    • 流出的数据流:从数据存储中读取数据,不改变原来的数据
  • 数据存储与数据流都是软件系统中的数据
  • 但是他们的状态不同,数据存储是静态数据,数据流是处于运动中的数据
    软件工程导论(中)_第22张图片

加工

  • 顶层的加工名就是整个软件系统的名字
  • 顶层以下层次的加工名应尽可能的体现加工的功能
  • 不要使用意思不明的命名:如处理1、处理2
    软件工程导论(中)_第23张图片

数据源或终点
在这里插入图片描述

  • 数据源点:从源点到系统的信息—提供数据—系统的输入—数据输入的源点—外部实体
  • 数据终点:从系统到终点的信息—使用数据—系统的输出—数据输出的终点—外部实体

软件工程导论(中)_第24张图片
软件工程导论(中)_第25张图片
软件工程导论(中)_第26张图片

SafeHome安全功能的顶层DFD例子:
软件工程导论(中)_第27张图片

SafeHome安全功能的0层DFD:
软件工程导论(中)_第28张图片
软件工程导论(中)_第29张图片

使用控制流建模

  • 为了完整的描述软件系统,还需借助"数据词典“对图中的每个元素给出定义,说明或解释
    • 数据字典是对数据流图中各成分描述、注释、说明的集合
    • 是对数据流图的重要补充。数据流图配以数据字典,从图形和文字两个方面对系统的逻辑模型进行完整的描述。
      软件工程导论(中)_第30张图片

数据字典的其他含义

  • 数据字典还有另一种含义,在数据库设计时的一种工具,用来描述数据库中的基本表的设计
  • 主要包括:字段名,数据类型,主键,外键等描述表的属性的内容

数据字典的每一条目的内容

  • 在数据流图中标识的数据源,数据流或外部实体的名称和别名
  • 数据类型
  • 所有以他作为输入流或输出流的转换列表
  • 如何使用该数据条目的简要说明
  • 数据条目的解释性说明
  • 其他补充说明,如取值范围与缺省值,有关的设计约束等

数据库数据字典

  • 数据库中所有模式对象的信息,如表,视图,簇,以及索引等
  • 列的缺省值
  • 约束信息的完整性
  • 用户及角色的名字,被授予的权限
  • 用户访问或使用的审计信息

软件工程导论(中)_第31张图片

离散数据流(事件)与普通数据流
软件工程导论(中)_第32张图片

你可能感兴趣的:(软件工程导论(中))