软件工程复习L5
- Software Design是后续开发步骤及软件维护工作的基础。
- 如果没有设计,只能建立一个不稳定的系统结构

The Design Process
- 设计是找出如何实现所有客户要求的创造性过程; 由此产生的计划也称为设计
- 早期设计决策针对系统架构(system's architecture)
- 后来的设计决策解决了如何实现各个单元(individual units)
Design is a Creative Process
- 利用现有解决方案的多种方法
- 克隆(Cloning):完全借用设计/代码,稍作调整
- 参考模型(Reference models):建议如何分解系统的通用架构

Design Process Model 设计过程模型
- 设计软件系统是一个迭代过程(iterative process)
- 最终的结果是软件架构文档(software architecture document)

The Role of the Architect

Decomposition and Views 分解和视图
- 系统关键元素的高级描述
- 创建具有越来越多细节的信息层次(hierarchy)结构

Popular Design Methods
- 一些设计问题没有现成的解决方案
- 设计师必须分解以隔离关键问题
- 一些流行的设计方法:
- 功能分解--Functional decomposition
- 面向数据的分解--Data-oriented decomposition
- 面向过程的分解--Process-oriented decomposition
- 面向事件的分解--Event-oriented decomposition
- 面向对象的设计--Object-oriented design

Architectural design 结构设计
- 识别子系统(sub-systems)并建立子系统控制和通信的框架(framework)
- 是设计过程的第一阶段
Architectural Styles and Strategies
Pipes-and-Filter
该系统有用于输入和输出的数据流(管道)和数据的转换(过滤器)

几个重要的属性
- 设计者可以将整个系统对输入和输出的影响理解为滤波器的组成
- 过滤器可以很容易地在其他系统上重复使用
- 系统进化很简单
- 允许并发执行过滤器
缺点
- 不适合处理交互式应用程序
数据流模型(Data-flow model)
例子:发票处理系统的流水线模型
Client-Server
- 两种类型的组件:
- 服务器组件提供服务
- 客户端使用请求/回复协议访问它们

该模型的主要组成部分
- 一组服务器(servers)
- 一组客户(clients)
- 一个网络(network)
例子

Peer-to-Peer (P2P)
- 每个组件都充当自己的进程,并充当其他对等组件的客户端和服务器(both a client and a server)。
- 任何组件都可以向任何其他对等组件发起请求(request)。
- 特征
- 扩大规模--Scale up well
- 增加系统容量--Increased system capabilities
- 高度容忍失败--Highly tolerant of failures

Publish-Subscribe
- 组件通过广播(broadcasting)和响应事件(reacting)进行交互
- 组件通过订阅(subscribe)事件来表达对事件的兴趣
- 当另一个组件宣布(发布)该事件发生时,订阅组件会收到通知

Repositories
- 两个组件
- 中央数据存储--central data store
- 对其进行操作以存储、检索和更新信息的组件的集合--store, retrieve and update information
- 挑战在于决定组件将如何交互
- A traditional database:事务触发流程执行
- A blackboard:中央存储控制触发过程

- 优点:开放(openness)
- 数据表示可供各种程序员(供应商)使用,因此他们可以构建访问存储库的工具 但也有一个缺点:数据格式必须是所有组件都可以接受的

- 黑板系统
- 专家系统
Layering
层是分层的(hierarchical)
- 每一层都为其外部提供服务,并充当其内部层的客户
好处
- 高度抽象--High levels of abstraction
- 添加和修改图层相对容易--add and modify a layer
缺点
- 构建系统层并不总是那么容易
- 系统性能可能会受到层间额外协调的影响--extra coordination
有时称为抽象机器模型(abstract machine model)
将系统组织成层
版本管理系统的分层模型



Combining Architectural Styles
实际的软件架构很少基于纯粹的一种风格
建筑风格可以通过多种方式组合
在不同的层使用不同的样式
使用混合样式对不同的组件或交互类型进行建模
如果架构表示为模型的集合,则必须创建文档以显示模型之间的关系
例子
Combination of Publish-Subscribe, Client-Server, and Repository Architecture Styles

Control styles
- 必须控制子系统(Sub-system)
- 两种通用控件样式
- 集中控制 Centralized control
- 一个子系统全面负责控制和启动和停止其他子系统
- 基于事件的控制 Event-based control
- 每个子系统都可以响应外部生成的事件
- 集中控制 Centralized control
Centralized control 集中控制
集中控制模式 Centralized control model
- 一个子系统被指定为系统控制器,负责管理其他子系统的执行
受控子系统是顺序执行还是并行执行 (sequentially or in parallel)
- 调用返回模型(call-return model)(自顶向下的子程序模型)
- 管理器模型(manager model),(一个系统组件被指定为系统管理器并控制其他系统进程的启动、停止和协调)
Call-return model

Real-time system control

Event-driven systems
- Event 事件
- 可能是一个信号,可以从菜单中获取一系列值或命令输入
- 两种事件驱动的控制模型
- 广播模型--Broadcast models
- 中断驱动模型--Interrupt-driven models
Broadcast model
- 子系统注册对特定事件的兴趣
- 所有事件都可以广播到所有子系统

Interrupt-driven control

Design Principles--Modularity 模块化
- 模块化是将系统的各个不相关方面分开的原则,以便可以单独研究每个方面
- 每个模块都将易于理解和开发
- 更容易定位故障(因为每个故障的可疑模块较少)
- 更容易更改系统(因为对一个模块的更改影响相对较少的其他模块
- 为了确定设计分离关注点的程度,我们使用两个衡量模块独立性的概念:耦合和内聚
Coupling 耦合
tightly coupled 紧密耦合
- 两个模块在彼此高度依赖时紧密耦合
loosely coupled 松散耦合
- 松散耦合的模块有一定的依赖性,但它们的互连性很弱
uncoupled 未耦合
- 未耦合的模块根本没有互连; 他们完全不相关

Cohesion 内聚
内聚是指模块内部元素(例如,数据、函数、内部模块)内部和之间的依赖关系

Design Principles
使用图表进行两种设计
- 扇入(fan-in)是指使用特定软件单元的单元数
- 扇出(fan-out)是指特定软件单元使用的单元数

扇出 = 一个模块直接调用。 3 <= fan-out <=9

- 扇入 = 直接调用该模块的模块数

在不破坏独立性的前提下,fan-in 大的比较好。
选择适当的深度、宽度、扇出和扇入

深度 = 分层的层数。过大表示分工过细。
宽度 = 同一层上模块数的最大值。过大表示系统复杂度大。
- 我们可以尝试使用称为sandwiching的技术打破使用图中的循环
- 循环的一个单元被分解成两个单元,这样新单元之一就没有依赖关系了
- 可以多次应用夹层,以打破紧耦合单元或长依赖链中的相互依赖关系



