🎓 总站 🏠 本课目录 01 概述 02 软件过程 03 需求工程 04 系统建模 05 概要设计 06 报告与高可信
软件系统综合课程设计 · 第5章

概要设计与体系结构

概要设计的任务与工程过程、软件设计原则(抽象/模块化/信息隐藏/模块独立性)、耦合与内聚等级,以及分层、C/S、B/S、MVC、管道过滤器等体系结构风格。

📚 学习进度
0%

🎯学习目标

  • 掌握系统概要设计的任务,理解概要设计的工程过程(9 个活动);
  • 掌握软件设计原则:抽象与逐步求精、模块化、信息隐藏、功能独立性;
  • 掌握衡量模块独立性的两个指标——耦合度(7 种)与内聚度(7 种);
  • 掌握软件体系结构的概念与三要素(构件、连接件、约束);
  • 理解常用体系结构风格:分层、C/S、B/S、MVC、管道过滤器、数据共享、总线等。

1概要设计的任务

设计阶段要解决的问题是系统"怎么做"。对较大规模项目,软件设计分两阶段:概要设计(系统/总体设计,确定基本框架)和详细设计(部件级设计,确定内部细节)。概要设计是从软件需求规格说明书出发,把问题结构(软件需求)映射为软件结构

💡 从建筑看软件设计好的软件设计应该:适用(符合开发目标、满足用户需求)、坚固(不含妨碍功能的缺陷)、赏心悦目(使用体验愉快)。

设计的元素

  • 软件系统采用什么样的体系结构;
  • 需要创建哪些功能模块以及模块间的关系;
  • 公共的数据结构;
  • 需要什么样的网络环境支持;
  • 需要什么类型的后台数据库。

概要设计的三大内容

🏛️

软件体系结构设计

选择适合需求的体系结构风格,开展物理架构、逻辑架构设计。如何划分系统、标识组件、组件如何通信。

🔌

接口设计

接口是外部可见操作的说明。包括与其他系统/硬件的外部接口、各构件间的内部接口。

🗃️

数据设计

确定文件系统结构、数据库模式/子模式,进行数据完整性和安全性设计,确定输入输出文件的数据结构。

2概要设计工程过程(9 个活动)

概要设计主要包括三方面:系统物理架构设计、软件结构设计(接口)、数据结构设计,具体任务分为 9 个活动:

#活动要点
1制定规范设计文档编制标准、信息编码格式、硬件/操作系统接口规约、设计目标与原则
2系统体系结构设计(物理架构)分解为独立子系统、分析通信与外部接口、确定软硬件/网络/数据环境、整体物理部署优化
3软件体系结构设计(逻辑结构)确定子系统模块元素、定义模块功能与接口、确定模块间调用返回关系、评估质量进行结构优化
4公共数据结构设计公共数据变量结构与作用范围、输入输出文件结构、数据库表/视图结构及数据完整性
5安全性设计操作权限、操作日志管理、文件与数据加密、特定功能校验
6故障处理设计对软硬件、网络故障进行备用设备、出错处理、数据备份
7可维护性设计设置系统监测专用模块、预计今后功能扩充的模块
8编写概要设计报告概要设计说明书、数据库设计说明书、测试初步计划
9概要设计评审需求确认、接口确认、模块确认(高内聚低耦合)、风险性、可维护性、质量
⭐ 概要设计评审要点需求确认:覆盖所有软件需求;② 接口确认:内/外部接口明确定义;③ 模块确认:满足高内聚低耦合、模块作用范围在控制范围内;④ 风险性;⑤ 可维护性;⑥ 质量。

3软件设计原则(一)

3.1 抽象与逐步求精

抽象:基本策略是从特殊到一般,上层概念是下层概念的抽象,下层概念是上层概念的精化;用于在软件规模逐渐增加的情况下控制复杂性。软件设计的抽象包括:

⚙️

过程抽象(功能抽象)

任何一个完成明确定义功能的操作都可以被当作单个实体对待。

📐

数据抽象

定义数据类型和施加于该类型对象的操作,并限定对象的取值范围。

逐步求精:把问题求解过程分解成若干步骤或阶段,每步比上步更精化、更接近解法。抽象与求精的关系:抽象描述过程和数据而忽略低层细节,求精则揭示低层细节;软件工程过程的每一阶段都是对软件解法的一次求精。

3.2 模块化

模块是数据说明、可执行语句等程序对象的集合,单独命名并可通过名字访问(如过程、函数、子程序、类、构件)。模块化是把软件按规定原则划分为较小的、相互独立但又相互关联的部件,体现了系统分解和抽象的过程。

💡 模块化的论据设 C(X) 为复杂性函数、E(X) 为工作量函数。规律:C(p1+p2)>C(p1)+C(p2),且若 C(p1)>C(p2) 则 E(p1)>E(p2),故 E(p1+p2)>E(p1)+E(p2)——将复杂问题分解成可管理的片段会使解决问题更容易。但模块数增加时模块间联系也增加,接合工作量随之上升,因此模块数有一个使总成本最小的合理区间。

3.3 信息隐藏

每个模块的实现细节对其它模块应该是隐蔽的;模块所包含的信息(数据和过程)不允许其它不需要这些信息的模块使用。通过信息隐藏可定义和实施对模块过程细节和局部数据结构的存取限制(如把成员设为 private)。

配套设计原则(GRASP)
  • 信息专家原则:将职责(方法)分配给具有实现该职责所需全部信息的直接类;尽量避免越级操作(如 Sale 类不越级操作 Item,只汇总 SalesLineItem)。
  • 创建者原则:若 A 组合/聚合/记录/紧密使用 B,则由 A 创建 B 的实例,保证外部类无法控制实例、避免级联影响。
  • 控制器原则:控制器是 UI 层之上的第一个对象,负责接收和处理 UI 产生的事件(如 Listener、Handler、Action、Controller),使功能与 UI 按钮解耦。

4功能独立性:耦合与内聚 ⭐(核心考点)

功能独立性指每个模块只完成系统要求的独立子功能,且与其他模块联系最少、接口简单。衡量指标为内聚度耦合度。目标:高内聚、低耦合

内聚(块内联系,越高越好)

低 ◀ 内聚性内聚性 ▶ 高 偶然 逻辑 时间 过程 通信 顺序 功能 模块独立性:弱 ◀──────────────────────▶ 强
图1 · 内聚的 7 个等级(从弱到强):偶然 < 逻辑 < 时间 < 过程 < 通信 < 顺序 < 功能
内聚类型说明(由弱到强)
偶然内聚各处理元素之间没有任何联系,最差,不易理解也不易修改
逻辑内聚执行几个逻辑上相似的功能,通过参数确定完成哪个功能
时间内聚把需要同时执行的动作组合(如初始化一组变量、同时打开若干文件)
过程内聚处理相关且必须以特定次序执行
通信内聚(信息内聚)所有处理元素在同一数据结构上操作,或使用相同输入/产生相同输出
顺序内聚各处理元素密切相关于同一功能且顺序执行,前一元素输出是下一元素输入
功能内聚最强,所有元素共同完成一个功能、缺一不可,最易理解修改、利于重用

耦合(模块间联系,越低越好)

低 ◀ 耦合性(好)耦合性 ▶ 高(差) 间接 数据 标记 控制 外部 公共 内容 模块独立性:强 ◀──────────────────────▶ 弱
图2 · 耦合的 7 个等级(从弱到强):间接 < 数据 < 标记(对象)< 控制 < 外部 < 公共 < 内容
耦合类型说明(由弱到强)
间接耦合两模块无直接关系,通过主模块的控制和调用间接实现,耦合最弱
数据耦合有调用/引用关系,传递的是数据值(值模型传递)
标记(对象)耦合传递的是数据对象/数据结构(引用模型传递)
控制耦合传递的信息中有控制信息(开关、标志),被调模块据此选择执行某功能;中等程度耦合
外部耦合一组模块访问同一全局简单变量,且不通过参数表传递
公共耦合通过公共数据环境(全局变量、共享区、文件等)相互作用,复杂度随模块数增加
内容耦合最高/最差,一模块直接访问另一模块内部数据、非正常入口转入、代码重叠
⭐ 高内聚低耦合原则总结① 具有高度相关功能的模块/类,可采用相对较高耦合度的交互方式连接(如继承、对象引用);② 功能差异较大的模块/类,应采用耦合度较低的交互方式连接(如接口调用、抽象类调用)。例:会员类系列内部用 protected/包内访问,外部模块通过 REST/Web Service 服务接口访问。

5软件体系结构概念与三要素

软件体系结构是软件模块(构件)之间关系的表示,决定整个系统的结构,也确定系统的质量。它高度抽象、超越了算法和数据结构,两个基本着眼点是系统的结构需求与实现间的交互。最早指出 SA 重要性的是 Dijkstra(1968:"the larger the project, the more essential the structuring!")。

⭐ 体系结构公式体系结构 = 构件 + 连接件 + 约束 + 质量。SA 在系统开发全过程中起中心作用,是设计/开发的起点和依据,是配置、运行和维护的指南。

三个核心元素

🧩

构件 Component

语义完整、语法正确、有可重用价值的单位软件。属性:自包容、严格封装、提供清楚接口规范。类型:纯计算单元、数据存储单元、管理器、控制器。
🔗

连接件 Connector

建立构件间交互及支配交互规则的构造模块。主要对构件之间的交互进行抽象。类型:过程调用、数据流、隐含触发器、消息传递类连接件。
📜

规约/协议 Protocol

连接的规约,建立在物理层之上的有意义信息形式的表达规定(参数个数/类型/次序、消息格式),目的是使双方能相互理解对方信息的语义。

构件 vs 连接件:构件主要负责业务层面的计算,连接件主要对构件之间的交互进行抽象。连接子内部规约包括通信链路、时序编排和监控设施三部分。

6常用体系结构风格 ⭐

体系结构风格描述某一特定应用领域中系统组织方式的惯用模式,从已有成功系统的组织结构中抽取而来。每种风格用构件、连接件、规则/配置三要素描述。

6.1 分层体系结构(Layered)

将系统组织成分层结构,每层包含一组相关功能,每层提供服务给毗邻的上一层,最底层是核心服务。是典型的调用-返回体系结构。

用户界面 用户界面管理 / 身份验证授权 核心业务逻辑 / 应用功能 系统实现程序 系统支持(操作系统、数据库等)
图3 · 分层体系结构:上层调用下一层,不能跨层调用
三要素内容
构件UI 层、业务逻辑层、数据实体层、算法层
连接件过程调用
规则/配置上层调用下一层,不能跨层调用

特征:关注点分离、层间隔离(不跨层调用,仅用下层接口)。优点:降低开发成本与复杂度、可扩展可维护、接口不变即可重用、某层接口变化只影响相邻上层。缺点:每层处理解释导致效率降低(可用缓存改善)、根本性需求改变可能产生跨层级联修改(可用依赖倒置改善)。适用于企业级应用、大型 Web、需特定安全/可靠性要求的系统。

6.2 C/S 与 B/S 体系结构

🖥️

C/S(客户端-服务器)

基于资源不对等实现共享,由服务器、客户应用程序、网络组成。客户端发请求、服务器返回响应。优点:强大的数据操作与事务处理、分布式任务、适应性强。缺点:客户端设计复杂、开发成本高、移植维护升级困难。

🌐

B/S(浏览器-服务器)

利用浏览器技术简化客户端、便于升级。由数据库服务器、Web 服务器、客户浏览器、网络组成。优点:安装修改维护在服务器端解决、自动升级、开放性好。缺点:安全性难控制、动态交互性不强、响应速度低。

C/S 多层演变:两层结构——信息表示与应用逻辑都放客户机("胖客户机"),服务器只管数据库事务;管理简单但客户机越多越难维护。② 三层结构——把易变化的应用逻辑提取到专门的"应用服务器"上(客户机变"瘦"),需求变化时只需改少数应用服务器。

6.3 MVC(模型-视图-控制器)

MVC 在传统 B/S 基础上加入控制器,由控制器决定视图与模型之间的依赖关系,保持功能内核独立于用户接口,适用于交互式软件开发。

控制器 C解释用户输入 视图 V数据显示 模型 M业务逻辑+数据 数据库 更新请求 变更通知
图4 · MVC:控制器解释用户输入→通知模型;模型状态改变触发变更-传播机制→通知视图刷新
组件职责对应传统 B/S
模型 Model管理应用行为和数据,响应状态查询与更改指令业务逻辑和数据
视图 View管理数据的显示用户界面
控制器 Controller解释用户的鼠标键盘输入,通知模型和视图更改新增元素

变更-传播机制是模型与视图、控制器之间的唯一连接,基于事件的隐式调用(构件不直接调用过程,而是触发或广播事件),保证模型与用户接口的一致性。适用于需要分离业务逻辑和用户界面、或支持多种用户界面(Web/移动/桌面)的应用。

6.4 数据流体系结构(管道-过滤器)

语境:数据源源不断产生,系统需对其进行处理。解决方案:把系统分解为几个连续处理步骤,步骤间通过数据流连接,一个步骤的输出是另一步骤的输入;每个步骤由过滤器(Filter)实现,数据传输由管道(Pipe)负责。包括管道过滤器风格和批处理风格。

过滤器1 过滤器2 过滤器3 管道
图5 · 管道-过滤器:每个过滤器独立处理,管道传输数据,一个的输出是下一个的输入

优点:整个系统的输入输出行为可理解为单个过滤器行为的叠加组合;任意两过滤器只要遵守共同规约即可相连;易于维护和升级。典型应用:编译器、Unix 管道、图像处理、信号处理、网络监控等。

6.5 其他风格

🗄️

数据共享(容器)体系结构

所有数据在一个中央容器中管理,可被所有组件访问,组件只通过容器交互。优点:组件独立、数据一致管理;缺点:容器是单点失效、通信低效、分布困难。适用数据密集型应用(金融、医疗、企业信息系统)。

🚌

总线体系结构

基于消息驱动和硬件总线概念,消息总线根据"构件-消息响应登记表"分派消息。优点:简单、灵活、可扩展;缺点:总线瓶颈、单点故障、实时性限制。适用小型/嵌入式系统(传感器网络、控制系统、家庭娱乐)。

7设计决策与"4+1"视图

体系结构设计决策

体系结构模式是经过实践验证、可在系统中复用的组织方式。体系结构设计是创造性过程,并不存在公式化的设计过程,取决于系统类型、架构师经验、系统特定需求。架构师应考虑:是否存在通用体系结构模板、系统如何分布到硬件/处理器、用什么策略控制构件运行。

⭐ 风格选择应根据非功能性需求
  • 性能:将关键操作局部化到少量构件、部署在同一台计算机、用大粒度构件节省通信开销;
  • 信息安全:使用层次化体系结构,把最关键资产放在最内层;
  • 可用性:包含冗余构件,以便不停机更换/替换构件;
  • 可维护性:使用细粒度、自包含的构件,将数据生产者与消费者分离。

软件体系结构的"4+1"视图模型

Kruchten(Rational,1995)提出用 5 个视图描述软件体系结构,每个视图只关心系统的一个侧面:

视图面向关注内容
逻辑视图最终用户功能和数据处理的逻辑组成(类图、对象模型、状态图)
开发视图(模块视图)系统开发人员子系统的分解、接口及依赖(包图、类图),建议 4-6 层
进程视图系统集成人员并发性、同步性、互操作性(进程、线程、通信)
物理(部署)视图系统部署人员功能如何分布于各节点,考虑性能、可用性、可靠性、可扩展性
场景视图(+1)用例汇总,将其他四个视图结合起来

重点例题

例题1:判断模块间耦合类型 给出代码片段:taxMaker.calculate(taxpayer.getFlag()),被调方法 calculate(int flag) 内部用 if(flag==0)... else if(flag==1)... 选择执行不同分支。 判断:传递的 flag 是控制变量(开关/标志),被调模块据此选择执行某功能,故为控制耦合(中等程度)。 风险:未来税率变化时会导致相关模块级联修改。改进:用多态或策略模式替代 flag 分支,降为数据/对象耦合。
例题2:识别体系结构风格 某电商系统:用户用浏览器访问,前端无业务逻辑,业务逻辑和数据实体在 Web 服务器计算,数据存于数据库服务器。 识别:客户端只需浏览器即为 B/S;业务逻辑/数据/UI 分层即分层体系结构;若进一步加入控制器分离视图与模型,则为 MVC。本系统综合应用分层 + B/S 多层体系结构模式。
例题3:高内聚低耦合分析 会员信息要满足三级等保,其他模块不得直接访问会员类方法;但会员相关类需频繁调用会员类,外部进销存模块也需访问会员信息。 方案:① 普通/微信/银卡/金卡会员形成继承链;② 公共成员设 protected 供子类内部访问;③ 高度相关的类置于同一包,用 default 修饰方法包内访问;④ 外部类通过服务接口或远程方法(REST/Web Service)访问。 原则:高度相关用较高耦合(继承、对象引用),差异较大用较低耦合(接口调用、抽象类)。

🎯自测(点击展开)

概要设计要解决系统的什么问题?包含哪三大内容?
解决系统"怎么做"(确定基本框架)。三大内容:软件体系结构设计、接口设计、数据设计。
衡量模块独立性的两个指标是什么?目标是什么?
内聚度和耦合度。目标是高内聚、低耦合。
内聚最强和最弱的类型分别是什么?
最强是功能内聚(所有元素共同完成一个功能),最弱是偶然内聚(各元素无任何联系)。
耦合最强(最差)和最弱(最好)的类型分别是什么?
最强(最差)是内容耦合,最弱(最好)是间接耦合。
体系结构的核心公式与三要素是什么?
体系结构=构件+连接件+约束+质量;三要素:构件、连接件、规则/配置。
MVC 相比传统 B/S 新增了什么元素?它的作用是什么?
新增控制器(Controller)。它解释用户输入、通知模型和视图更改,决定视图与模型之间的依赖关系。

📝强化题库

选择题点选即时判分;填空题输入后"检查"或"显示答案"。

已答 0/0答对 0正确率
已答 0/0答对 0