• 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)结构

  • 一些设计问题没有现成的解决方案
    • 设计师必须分解以隔离关键问题
  • 一些流行的设计方法:
    • 功能分解--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 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 耦合
  1. tightly coupled 紧密耦合

    • 两个模块在彼此高度依赖时紧密耦合
  2. loosely coupled 松散耦合

    • 松散耦合的模块有一定的依赖性,但它们的互连性很弱
  3. uncoupled 未耦合

    • 未耦合的模块根本没有互连; 他们完全不相关

Cohesion 内聚

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

Design Principles

  • 使用图表进行两种设计

    • 扇入(fan-in)是指使用特定软件单元的单元数
    • 扇出(fan-out)是指特定软件单元使用的单元数

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

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

  • 在不破坏独立性的前提下,fan-in 大的比较好。

  • 选择适当的深度、宽度、扇出和扇入

深度 = 分层的层数。过大表示分工过细。

宽度 = 同一层上模块数的最大值。过大表示系统复杂度大。

  • 我们可以尝试使用称为sandwiching的技术打破使用图中的循环
    • 循环的一个单元被分解成两个单元,这样新单元之一就没有依赖关系了
    • 可以多次应用夹层,以打破紧耦合单元或长依赖链中的相互依赖关系