软件体系结构是具有一定形式的结构化元素,抽象的讲,软件体系结构包括构成系统的设计元素的描述,设计元素的交互,设计元素组合的模式,以及在这些模式中的约束。具体的讲,体系结构 = 组件+连接件+约束
组件:具有某种功能的可重用的软件模块单元,表示了系统中主要的计算单元和数据存储。
连接件:表示了组件之间的交互,简单的连接件有:管道,过程调用,事件广播等,复杂的连接件有:客户-服务器通信协议,数据库和应用之间SQL连接等。
约束:表示了组件和连接件的拓扑逻辑和约束。
组件: filters -->处理数据流,一个过滤器封装了一个处理步骤。
连接件:pipes --> 连接一个源和一个目的过滤器。
每个过滤器都有一组输入集和输出集。过滤器从管道中读入数据流,对输入流进行内部转换和增量计算(丰富,精炼,转换,融合,分解),然后产生输出数据流并写入管道中。
特点:
编译器、Unix管道、图像处理,信号处理,声音与图像处理
优点
缺点:
组件:过程和明确可见的数据
连接件:过程调用和显式的共享数据
控制结构:单线程
调用和定义层次结构,子系统通常通过模块化来定义。
系统通常会被组织成一个主程序和一系列子程序的集合。主程序担当子程序的驱动器,为子程序提供一个人控制环路,使子程序以某种次序顺序执行。
组件:对象(抽象数据类型的实例)
连接件:过程调用
在基于面向对象的模式中,操作和数据绑定在一起,隐藏实现和其他秘密。对象通过过程调用来实现交互。有两个重要方面:
优点:
缺点:
组件: 在某些层中实现虚拟机
连接件: 协议, 规定了层次之间的交互方式
拓扑结构: 限制相邻层之间的交互
优点:
缺点
服务器(后台)负责数据管理,客户机(前台)完成与用户的交互任务。“胖客户机,瘦服务器”
– 对客户端软硬件配置要求较高,客户端臃肿
– 客户端程序设计复杂
– 数据安全性不好。客户端程序可以直接访问数据库服务器。
– 信息内容和形式单一
– 用户界面风格不一,使用繁杂,不利用推广使用
– 软件维护与升级困难。每个客户机上的软件都需要维护
与二层C/S结构相比,增加了一个应用服务器。
应用功能分为表示层、功能层、数据层三层。
– 表示层是应用的用户接口部分。通常使用图形用户界面
– 功能层是应用的主体,实现具体的业务处理逻辑
– 数据层是数据库管理系统。
– 以上三层逻辑上独立。
整个应用逻辑驻留在应用服务器上,只有表示层存在于客户机上:“瘦客户机”
B/S体系结构是三层C/S体系结构的特例,客户端有http浏览器即可
• 只能“拉”,不能“推”
• 客户之间的通信只能通过服务器中转
• 对客户机资源和其他网络资源的利用受限
• B/S结构的安全性较难控制(SQL注入攻击…)
• B/S结构的应用系统在数据查询等相应速度上,要远远低于C/S体系结构
• 服务器的负荷大,客户机的资源浪费
Data-centered style architectures involve a shared
data source approach to information passing.以数据为中心的风格架构涉及到信息传递的共享数据源方法。
典例: 注册表 剪切板
仓库是存储和维护数据的中心场所。
组件: 中心数据结构,表示当前数据的状态
连接件:仓库与独立构件之间的交互
应用场合:数据库、仓库形式的编译器结构、仓库形式的编译器结构
✓ 事件的触发者并不知道哪些构件会被这些事件影响,相互保持独立。
✓ 不能假定构件的处理顺序,甚至不知道哪些过程会被调用。
✓ 各个构件之间彼此之间无连接关系,各自独立存在,通过对事件的发布和注册实现关联。
A component(Event Source) can annonce (or broadcast) one or more events. 一个组件可以广播一些事件。
Other components(Event Handlers) in the system can register an interest in an event by associating a procedure with it. 系统中的其它构件可以注册自己感兴趣的事件,并将自己的某个过程与相应的事件进行关联。
When the event is announced the system (Event Manager) itself invokes all of the procedures that have been registered for the event. 当一个事件被发布,系统自动调用在该事件中注册的所有过程。
Event Source:debugger (调试器)
Event Handler:editor and variable monitor (编辑器与变量监视器)
Event Manager:IDE (集成开发环境)
✓ 编辑器与变量监视器向调试器注册,接收“断点事件”;
✓ 遇到断点,调试器发布事件,从而触发“编辑器”与“变量监测器”
✓ 编辑器将源代码滚动到断点处;
✓ 变量监测器则更新当前变量值并显示出来。
This module is usually called Observable/Observer (被观察者/观察者).
Each module allows other modules to declare interest in events that they are sending. (每一个模块都允许其他模块向自己所能发送的某些消息表明兴趣)
Whenever a module sends an event, it sends that event toexactly those modules that registered interest in that event.
事件派遣模块是负责接收到来的事件并派遣它们到其它模块。
全广播式(All broadcasting) :派遣模块将事件广播到所有的模块,但只有感兴趣的模块才去取出事件并触发自身的行为;
选择广播式(Selected broadcasting) :派遣模块将事件送到那些已经注册的模块中。
选择广播式的两种策略:基于事件被执行的方式
Point-to-Point (message queue)(点对点模式:基于消息队列)
Publish-Subscribe(发布-订阅模式)
◆ 1.从读者的角度写。
◆ 2.避免不必要的重复。
◆ 3.避免歧义。
◆ 4.使用标准组织结构。
◆ 5.记录理由。
◆ 6.保持文档时效性但不是频繁更新(有限的稳定性)。
◆ 7.审查文档是否符合需求
“4+1”视图模型从5个不同的视角包括逻辑视图、进程视图、物理视图、开发视图和场景视图
来描述软件体系结构。每一个视图只关心系统的一个侧面,只有5个视图结合在一起才能反映系统的软件体系结构的全部内容。
用例视图 (场景)
◼ 从外部世界的角度描述正在建模的系统的功能。
◼ 需要使用此视图来描述系统应该执行的操作。 所有
其他视图都依靠用例视图(场景)来指导它们,这
就是将模型称为4 + 1的原因。
◼ 该视图通常包含用例图,描述和概述图。
理解系统功能需求,系统提供的功能的描述。
用于显示若干角色以及这些角色与系统提供的用例之间的连接关系。
重要的是记住用例代表了系统的外部视图。因此,不要期望用例与系统内部的类之间存在任何关联。
逻辑视图
◼ 描述系统各部分的抽象描述。用于建模系统的组成部分以及各组成部分之间的交互方式。
◼ 通常包括类图,对象图,状态图和协作图。
类图表示系统中的类和类与类之间的关系,它是对系统静态结构的描述。
对象图是某个时间点系统中对象的快照,因为它显示的是实例而不是类,所以通常称为实例图。
状态图是描述类的对象所有可能的状态以及事件发生时状态的转移条件。
协作图是一种交互图,强调的是发送和接收消息的对象之间的组织结构。一个协作图显示了一系列的对象及对象之间的联系以及对象间发送和接收的消息。
过程视图
◼ 描述系统中的进程。 当 可视化系统中一定会发生的事情时,此视图特别有用。
◼ 该视图通常包含活动图。
描述满足用例要求所要进行的活动以及活动间的约束关系,有利于识别并行活动
开发视图
◼ 描述系统的各部分如何被组织为模块和组件。管理系统体系结构中的层非常有用。
◼ 该视图通常包含包图和组件图。
包是在UML中用类似于文件夹的符号表示的模型元素的组合,允许从UML中获取任何结构,并将其元素分组到更高级别的单元中。
组件图描述代码构件的物理结构及各构件之间的依赖关系。将系统划分为组件并希望通过接口或组件细分为较低级别的结构来显示其相互关系
物理视图
◼ 描述如何将前三个视图中所述的系统设计实现为一组现实世界的实体。该视图中的图表展示了抽象部分如何映射到最终部署的系统中。
◼ 该视图通常包含部署图。
部署图定义系统中软硬件的物理体系结构。描述了一个运行时的硬件结点,以及在这些结点上运行的软件组件的静态视图。 显示了系统的硬件,安装在硬件上的软件,以及用于连接异构的机器之间的中间件。
➢ 刺激源(source):谁造成的刺激
➢ 刺激(stimulus):一个影响系统的情况
➢ 制品(artifact):系统被影响的部分
➢ 环境(environment):刺激发生时系统所处的状态
➢ 响应(response):刺激所产生的结果
➢ 响应衡量指标(response measure):如何评估响应
✓ 是否发生了故障(无法提供正常的服务,被外界发现)
✓ 故障的后果
✓ 可用(或故障)时间百分比
✓ 修复故障所需的时间
✓ 平均无故障时间
➢刺激源
✓ 故障的迹象(来自内部或外部)
➢刺激
✓ 系统出错
✓ 系统崩溃(反复出错)
✓ 给出结果不准时(早或晚)
✓ 给出错误结果
➢制品
✓ 计算 or 存储 or 网络传输
➢环境
✓ 正常状态 or “亚健康”状态
➢响应
✓ 记录日志(错误报告),回传给厂家
✓ 通知管理员或其他系统
✓ 关闭系统,系统在维修期间不可用
➢响应衡量指标
✓ 故障时间百分比、修复故障所需时间、平均无故障时间……
➢ 方向1:故障检测
监控组件不定期向被监控组件发出ping消息,并根据收到的echo消息(是否收到、延时)做出响应
被监控组件定期向监控组件发出心跳消息
在节点间保持周期性的心跳信号以检测各个节点的状态。若连续未收到的心跳信号到了一定的数目,就认为相应的系统已经出现故障。
抛出 + 捕获 + 处理
需要编程语言支持
➢ 方向2:故障恢复
投票
果不同,则少数服从多数
硬件平台上开发
主动冗余
A算出的结果
被动冗余
新为A的状态。
内测
开发人员修正bug,并在内部进行测试,确认无误后再发布补丁
检查点/回滚
定期保存,便于恢复
➢ 方向3:故障避免
✓修改的成本
✓系统的哪些部分被修改
✓修改发生的时间
✓修改由谁来进行
目标:降低修改的时间和成本
限制修改范围:让修改所影响的软件范围尽可能的小
模块高内聚、低耦合:尽量把对程序的修改控制在一个模块内,可以借助框架、中间件
考虑到可能会发生的修改
➢有助于评估模块间责任的划分
➢ 让一个点的修改只影响一个模块
➢ 避免完全无关的多个修改会影响同一个模块
让模块通用:“解释器”风格的思路
隐藏信息:面向对象机制中的可访问性(public/private)
维持接口不变:在接口不变的情况下,接口连接的双方可以独立变化
限制通信路径:设计模式中的Façade模式
使用中介
➢ 数据中介:共享数据的风格
➢ 服务中介:设计模式中的bridge、factory method等模式
命名服务器(name server):查询所需资源 / 对象的位置,解决位置依赖
按需创建实例:借助设计模式中的创建型模式
延迟绑定时间:让软件在运行期间仍可进行灵活修改
配置文件:修改配置文件,而不用修改代码
发布-订阅模式
➢ 软件体系风格部分已有介绍(事件系统)
➢ 设计模式中的“观察者模式”
- 多态:用不同的子类,实现不同的功能
✓ 系统响应事件的速度
✓ 和事件的数量和到达模式有关
✓ 处理事件所花的时间
✓ 单位时间内处理事件的数目
✓ 处理的错误率/丢失率
方向1:资源的需求
- 在要处理的数据量不变的情况下,提高计算效率
➢ 使用更高效率的算法
➢ 减少处理事件时对资源的占用
- 减少要处理的数据总量
➢ 控制事件到来的速率
➢ 只抽取一部分请求来处理
- 限制执行时间
➢ 在规定时间内得到近似解
- 限制待处理事件队列长度
➢ 直接放弃处理一部分事件
方向2:资源的管理
利用并发机制:多线程、多进程、多核、多机……
增加可用资源: 计算资源、存储资源、带宽资源……
方向3:资源的仲裁
➢ 先来先服务
➢ 固定优先级调度➢ 动态优先级
✓ 在保证合法用户使用系统的前提下,抵抗对系统的攻击
- 用户的证实:密码、验证码、生物识别……
- 用户的授权: 确认用户的操作是在其权限范围
- 维持数据的保密性:给数据和传输过程加密
- 维持数据的完整性:MD5码校验
- 减少暴露:关闭无用端口、自启动的服务、无线路由SSID等
- 限制访问:白名单、黑名单
方向2:检测攻击
软件和人结合:入侵检测系统、安全专家
方向3:从攻击中恢复
恢复状态:使用“可用性”中的相关策略
攻击者的识别:也能震慑潜在的攻击者
✓ 让软件的bug容易被测试出来
✓ 验证软件产品与它的需求规格是否匹配(存在不符或缺失)
✓ 使用最小的成本和工作量来验证软件的质量
黑盒测试
记录 / 回放: 自动化/半自动化测试
把接口和实现分离开:不同的排序算法,使用相同的接口提供专用的测试路径
白盒测试
内部监控:IDE提供的断点等调试工具、WinDbg等工具
Appium(APP UI测试)
Selenium(Web UI测试)
JMeter(接口测试、性能测试)
方向1:运行时策略
- 系统猜测用户要完成的任务:输入法联想、搜索引擎联想
- 系统给用户适当的反馈:提示拷贝文件所需的剩余时间、浏览器打开页面的进度
- 系统给用户提供一致的体验:鼠标提供DPI调整,适应不同的分辨率
- 支持撤销操作:减少误操作的影响
方向2:设计时策略
把用户界面和系统其它部分隔离开:MVC模式,支持用户界面的独立修改(甚至用户可以自行修改用户界面)
效用是树的根结点,代表系统的整体质量。质量属性构成树的二级节点。在每个质量属性下对该质量属性做了进一步的说明。所设置的优先级是用高(H)、中(M)、低(L)的形式。
(M,L)优先级解释
- 第一个字母代表:每个场景对系统成功的重要影响程度
- 第二个字母代表:体系结构设计师所估计的实现这种场景的难度
A sensitivity point is a property of one or more components (and/or component relationships) that is critical for achieving a particular quality attribute response.
“The level of confidentiality in a virtual private network might be sensitive to the number of bits of encryption. ”敏感点是一个或多个组件(和/或组件关系)的属性,对于实现特定的质量属性响应至关重要。
e.g. 虚拟专用网络的保密级别可能对加密的位数很敏感。
A tradeoff point is a property that affects more than one attribute and is a sensitivity point for more than one attribute.
“Changing the level of encryption could have a significant impact on both security and performance.”权衡点是影响多个属性和的属性,是多个属性的敏感点。
e.g.“改变加密级别可能会对安全性和性能产生重大影响。
risks
A risk is a potentially problematic architectural decision.
“The level of confidentiality in a virtual private network might be sensitive to the number of bits of encryption. ”风险是一个潜在的有问题的架构决策。
e.g.“虚拟专用网络的机密程度可能对加密的比特数很敏感。”
Non-risks are good architectural decisions that are deemed safe upon
analysis.
“Assuming message arrival rates of once per second, a processing
time of less than 30 ms, and the existence of one higher priority
process, a 1 second soft deadline seems reasonable.”无风险是被认为是安全的良好架构决策分析。
e.g.假定消息的到达速率是每秒一次,一次处理的时间小于30ms。如果对一个更高优先级的处理的响应时间要求是1秒钟,此系统可行
客观题(30分)
两道简答题(5*2 = 10)
十道选择题(2*10 = 20)
六种质量属性的提升策略
看图片中所给的是哪种体系结构风格
UML各种图的功能和结构
三道大题(70分)
刚考完试,发波笔记攒人品,过过过! 2020/8/18
《软件体系结构》 Mary Shaw David garlan著
课件