软件体系结构——第八章<构架设计>

一、过渡到设计

从需求到分析:

image.png

从分析到设计:

image.png

有三种不同类型的设计策略:

①D-设计(Decomposition design)

  • 分解设计策略,将系统映射为构件片(component pieces),如:用于开发管理信息系统的业务逻辑

②FP-设计(Family Pattern design)

  • 通用性设计策略,主要探求问题的本质特征,主要用于通用产品的设计

③I-设计(Invention design)

  • 基于概念化原型作系统分析,主要用于没有明确需求的软件产品

分析(做什么):

  • 关注业务问题的理解

  • 理想化设计

  • 行为

  • 系统结构

  • 功能需求

  • 一个小的模型

设计(怎么做):

  • 关注解决方案的理解

  • 操作和属性

  • 性能

  • 接近实际的代码

  • 对象的生命周期

  • 非功能需求

  • 一个大的模型

二、构架设计基础

构架(Architecture)是一个系统的组织结构,包括系统分解后的各个组成部分、相互之间的连接性、交互机制和指导系统设计的相关规则。

构架设计即在系统的全局范围内,以分析活动的结果为出发点,主要工作如下:

  • 将现有的“分析类”映射成设计模型中的“设计元素”

  • 明确适用于系统的“设计机制”

  • 调整“设计元素”的内容逐渐充实为系统“构架”

构架设计需要做的具体工作:

  • 确定核心元素:在构架的中高层,以“分析类”为出发点,确定相应的“核心设计元素”

  • 引入外围元素:在构架的中低层,以“分析机制”为出发点,确定满足分析类要求的“设计机制”,并将相关的内容引入到设计模型

  • 优化组织结构:按照高内聚、低耦合的基本原则,整理并逐渐充实构架的层次和内容

  • 定义设计后的组织结构:构架设计还应该考虑设计完成后系统实现、运行以及部署等阶段的组织结构——包图、部署视图

UML和构架设计:

UML提供了相关的构架设计建模工具

  • 包图(Package diagram)

  • 包(Package)、依赖关系(Dependency)

  • 子系统(Subsystem)、接口(Interface)

  • 层(Layer)

是一种将模型元素分组的机制,是一个容器——用来包含其他的UML元素

包主要用于

  • 组织模型元素、配置管理单元

分包的原则(高内聚、低耦合)

  • 职责相似的:将一组职责相似、但以不同方式实现的类归为一组有意义的包;如java类库中的javax.swing.border包

  • 有协作关系的:包含了各种不同类型的类,它们之间通过相互协作实现一个意义重大的职责

包的命名和可见性

包图(Package Diagram)是一种维护和描述系统总体结构模型的重要建模工具。图中各个包与包之间的依赖关系,描述了系统中的模块与模块之间的依赖关系。

包的内部元素的可见性:private(-)、protected(#)或public(+)。

image.png

包的构造型和子系统

  • 业务分析模型包
  • 业务设计包
  • 业务用例模型包
  • CORBAModule包

包的嵌套

包的嵌套可以清晰的表现系统模型元素之间的关系。注意:包的嵌套不宜过深,包的嵌套的层数一般以2到3层为宜。

image.png

包的联系——包之间只具有依赖关系

  • 包的依赖关系同样是使用一根虚箭头线表示,虚箭头线从依赖源指向独立目的包。

  • 注意:独立包一旦修改,则依赖源必须做检查是否修改

image.png

包元素的可见性

image.png

包设计原则:

  • 避免循环依赖

image.png

  • 避免分支依赖

image.png

在项目中使用包

①确立包图的分类

  • 学生信息管理系统,可采用MVC构架进行包的划分——在逻辑视图(Logical view)下确定三个包,分别为模型包、视图包和控制包。

  • 模型包:是对系统应用功能的抽象,包中的各个类封装了系统的状态——系统行为的变化。

  • 视图包:是对系统数据表达的抽象,包中的各个类对用户的数据进行表达,并维护与模型中的各个类数据的一致性。

  • 控制包:是对用户与系统交互事件的抽象,它把用户的操作变成系统的事件,根据用户的操作和系统的上下文(业务处理逻辑)来调用不同的数据——交互行为的变化。

②创建包和包的关系

image.png

三、确定设计元素

设计元素:是能够直接用于实现(编码)的模型元素,主要包括:

  • 包(Package)

  • 设计类(Design Classes)

  • 子系统(Subsystem)

  • 接口(Interface)

  • 主动类(Active Class):系统内的控制线程

确定设计元素的目的:改进(调整)现有分析类,使之成为适当的设计模型元素

设计类是设计模型中最基本、最主要的构成单位。确定方法如下:

分析类可以被直接映射到设计类,如果:是一个简单类、或表示一个简单的逻辑抽象

更复杂的分析类可能是:

  • 分解成多个设计类

  • 成为一个包

  • 成为一个接口和子系统

  • 根据实际业务需要进行的任何组合

一个分析类,可能映射为:

  • 一个简单的设计类

  • 一个设计类的一部分

  • 一个聚合类

  • 同一个类继承而来的一组类

  • 一组功能相关的类(功能相关的打到一个包里)

  • 一个子系统(含接口)、或一个关系——可能成为设计模型中的一个类(即关联类)

打包机制

分析时,用B-C-E备选构架对分析类进行分组;

设计时,由于大量设计元素的引入,因此需要定义更合理的分组(封装)机制对设计类进行打包——打包设计类。

分组(封装)标准可以基于多种不同的因素:

  • 配置单元(按主题)

  • 开发团队中的资源分配

  • 反映用户类型(参与者的角色)

  • 表示已有产品和服务

实例:旅游申请系统分包考虑

考虑的几个要素

  • 考虑用户界面的不确定性,将用户界面单独打包(User Interface)

  • 系统核心业务为申请旅游团。因此,与申请相关的业务打包为Application Services包——负责前端与申请相关的业务处理

  • 与参与者相关业务可以考虑和其它系统的复用(如与CRM系统),与路线管理相关的业务也存在一定的复用性,均以单独包形式作为旅游业务相关的基础业务服务单元(Tour Artifaces)

旅游申请系统分包结果

image.png

如何确定接口和子系统?

接口(Interface)是类、子系统或构件对外提供服务的操作集合。主要表现为:

  • 接口允许用户以公开的方式定义多态,并且和实现没有直接联系(实现由具体类来完成)

  • 接口支持“即插即用”的结构,便于扩展

image.png

子系统(Subsystem)是一种介于包和类之间的一种设计机制,它可实现一个或多个接口所定义的行为

  • 具有包的语义:能够包含其它模型元素

  • 具有类的语义:具有行为

image.png

子系统的作用:

  • 完全封装了行为(包、类的定义)

  • 利用清晰的接口代表所拥有的能力(便于复用)

  • 利用多态机制可以定义不同的实现

子系统 vs 包:

子系统:

  • 提供行为(接口)

  • 完全封装实现细节

  • 容易替换

包:

  • 不提供行为

  • 不完全封装实现细节

  • 难以替换

子系统的主要用途:

子系统可以将系统划分成独立的部分,将被实现为独立的构件(类构件),这些构件在保持结构不变的情况下,可以:

  • 进行排序、配置、分发

  • 开发,只要保持接口不变

  • 部署到不同分布的节点上

  • 构件内部可任意变更,而不影响到其它系统的正常使用

子系统也可用于

  • 将系统划分成若干个独立单元

  • 表示设计中的现有产品或外部系统(须提供接口)

子系统的设计原则:

目标

  • 松散耦合

  • 可替换的,plug-and-play

  • 通过接口隔离变更

  • 自身可独立的改进

设计原则

  • 不要暴露细节,只提供接口

  • 外部访问时仅依赖于接口

子系统的设计步骤:

第一步:将系统的行为分发到各个子系统元素中:分发子系统的职责

第二步:描述子系统中的元素

第三步:描述子系统的依赖关系

确定候选的子系统:

①可能发展为子系统的分析类

  • 提供复杂服务、通用功能的类

  • 边界类(用户界面和外部系统接口)

②设计中现存产品或外部系统

  • 通信软件

  • 数据库访问支持

  • 类型和数据结构

  • 通用程序

  • 专业应用软件产品

如何确定子系统?

如果某个分析类相当复杂,且包含的行为无法由单个类(或几个类的简单组合)来独自负责执行,则应考虑将该分析类映射为子系统。

映射的细节主要有:

  • 使用设计子系统来封装类间的协作

  • 子系统客户在完全不知道内部设计的情况下可以很方便的使用它提供的服务(即接口)

  • 子系统内部的实现细节则延迟到子系统设计阶段

image.png

确定子系统的接口:

目的

  • 基于子系统的职责确定其接口或接口数目

步骤

  • 为每个子系统确定一个备选接口集

  • 寻找接口之间的相似点——定义公共接口

  • 定义接口依赖关系

  • 将接口映射到子系统——给子系统分配职责

  • 定义接口所指定的行为——接口方法的定义

  • 将接口打包

如何确定接口?

  • 接口名:反映在系统中的作用

  • 接口描述:表达职责(接口功能描述)

  • 接口操作的定义:名称应反映出操作的结果——具有鲜明的含义,说明操作做什么,以及所有参数和结果

  • 接口文档:交互图、状态图、测试计划…

如何进行接口设计?

接口说明了子系统对外所能提供的一组操作,隐藏了子系统的内部实现细节

接口常见的设计模式——遵循接口隔离原则:

  • 确定系统的内聚部分——功能相关的、职责相似的

  • 将这些内聚部分打包到一个<<subsystem>>

  • 为该子系统设计<<Interface>>,并定义接口的一系列操作——对外提供的公共消息接口和操作名称

四、引入设计机制

构架机制

软件系统提供的三类构架机制:分析机制(概念)、设计机制(具体)、实现机制(实际)

  • 分析机制用于对构架层的问题进行记录——如何描述业务需求;如,持久性、分布、安全性, 等

  • 设计机制用于实现相应的分析机制,即在分析机制的框架中添加实现细节——即用具体的设计方案来解决问题

    • 其中:设计模式也是设计机制的一种。如,MVC
  • 实现机制则是运用特定的实现技术来编码实现相应的设计机制

构架机制举例:

image.png

如何应用构架机制?

构架机制可以被视为一种模式(参数化协作)

image.png

如何确定设计机制?

  • 需要为分析机制选定合适的设计机制(通常是套用现成的设计模式),并描述其设计原理,以便构件设计(详细设计)时使用

  • 从分析机制到设计机制,如,持久性设计机制,可描述为——持久性:RDBMS:JDBC

描述构架机制的典型应用场景

不同的构架机制有不同的使用场景,可以采用UML交互图对构架机制的各种典型应用场景进行建模——顺序图。

五、描述系统部署

描述系统部署:

构架分析中,分布也是一种分析机制,用来指明哪些类需要支持分布式访问;而构架设计阶段,需要描述与分布相关的设计细节,主要工作为:

  • 选择并设计系统的分布式结构

    • 结合通用的分布模式,设计目标系统的分布式结构
  • 在物理节点间部署系统功能,即进行部署建模

    • 利用UML部署模型描述设计元素、进程、工件(软件制品)等物理节点上的部署情况
  • 设计并实现分布机制

    • 针对分布机制,描述其相应的设计和实现机制

如何描述分布?

描述分布活动重点在于设计构架的部署视图(Deployment View)

  • 若系统只运行在一个节点上,就不需要单独的部署模型——即不需要进行部署视图建模

描述分布的目的

  • 说明如何在物理节点间分布(部署)系统功能

  • 仅对分布式系统有效

为什么要分布?

分布式应用是现代软件发展的主流趋势,能够解决的问题如:

  • 减少处理器负载

  • 完成特殊处理需求

  • 性能匹配

  • 经济考虑

  • 对系统进行分布式访问

通用的分布模式

客户机(Client)/服务器(Server)

  • 三层构架

  • 胖客户机(Fat Client)构架

  • 胖服务器(Fat Server)构架

  • 分布式客户机/服务器

对等结构(Peer-to-Peer)

  • 系统中的节点没有客户端和服务器的概念,既可以作为客户端请求服务,又可作为服务器提供服务。

部署图建模元素

节点(Node):物理运行时的计算资源

  • 处理器节点:执行系统软件(服务器、终端)

  • 设备节点:支持设备(其他外围设备)

连接(Connection):

  • 通信机制

  • 物理媒介

  • 软件协议

image.png

什么是部署图?

部署图(Deployment Diagram)描述处理器、设备、软件组件在实际运行时的构架。

用途:它是系统网络拓扑结构的最终物理描述——即描述硬件单元和运行在硬件单元上的软件结构。

image.png

实例:医院预约挂号系统部署模型

image.png

posted @ 2022-05-04 17:18  我在吃大西瓜呢  阅读(278)  评论(0编辑  收藏  举报