考试题型:选择、简答、设计
目录
- 软件设计模式
- 软件体系结构
软件设计模式
软件体系结构
第五章 软件体系结构概述
1. 定义
SEI软件体系结构讨论群定义如下:一个程序/系统构件的结构,它们之间的相互关系, 以及在设计和交付的整个过程中的原则和指导方针。
一般来说,软件体系结构定义需要考虑到系统中的构件及其它们之间的相互作用。
Kruchten指出,软件体系结构具有四个角度,它们从不同方面对系统进行描述,其中概念角度描述系统的主要构件及它们之间的关系;模块角度包含功能分解与层次结构;运行角度描述了一个系统的动态结构;代码角度描述了各种代码和库函数在开发环境中的组织。
David Garlan和Dewne Perry于1995年在IEEE软件工程学报上采用如下的定义:软件体系结构是一个程序/系统各构件的结构、它们之间的相互关系以及进行设计的原则和随时间进化的指导方针。
Barry Boehm和他的学生提出,一个软件体系结构包括一个软件和系统构件,互联及约束的集合;一个系统需求说明的集合;一个基本原理用以说明这一构件,互联和约束能够满足系统需求。
1997年,Bass,Ctements和Kazman在《实用软件体系结构》一书中给出如下的定义:一个程序或计算机系统的软件体系结构包括一个或一组软件构件、软件构件的外部的可见特性及其相互关系。其中,“软件外部的可见特性”是指软件构件提供的服务、性能、特性、错误处理、共享资源使用等。
Mary Shaw和David Garlan认为软件体系结构包括构成系统的设计元素的描述,设计元素的交互,设计元素组合的模式,以及在这些模式中的约束。
软件体系结构包括构件(Component)、连接件(Connector)和约束(Constraint)或配置(Configuration)三大要素。
国内普遍接受的定义:软件体系结构包括构件、连接件和约束,它是可预制和可重构的软件框架结构。
构件是可预制和可重用的软件部件,是组成体系结构的基本计算单元或数据存储单元
连接件也是可预制和可重用的软件部件,是构件之间的连接单元
构件和连接件之间的关系用约束来描述
软件体系结构 = 构件 + 连接件 + 约束
2. 优势
- 容易理解
- 它从一个高层设计的抽象层次来表征一个系统
- 简化了我们理解庞大系统的能力
- 重用
- 重用大的构件
- 重用一些集成构件的框架
- 重用特定领域的软件体系结构
- 重用设计模式
- 控制成本
- 系统维护者可以更好的理解变更带来的影响,因而可以更加精确的估算变更所需的成本
- 可分析性
- 对系统的一致性检查提供高层次的视图
- 研究系统是否与某种体系结构风格相符合
- 对符合特定风格的特定领域系统的体系结构分析
- 分析依赖于其中的构件
3. 经典软件体系结构风格
- 调用-返回风格软件体系结构
- 数据流风格软件体系结构
- 基于事件的软件体系结构
- 层次软件体系结构
- MVC软件体系结构
第六章 经典软件体系结构
1. 调用-返回风格软件体系结构
1.1 非结构化编程简介
- 非结构化编程技术是最早的编程范型。
- 一个由非结构化语言,例如:汇编语言,编写的程序通常包含一系列有序的命令(语句),通常是每个语句占一行,每行都有标记一个行号或者标签,允许程序执行流可以依据行号从一行跳到程序的其他指定的行。
- 非结构化编程引入基本的循环、分支与跳跃等控制流的概念。
- 非结构化编程中的子程序允许有多个入口和多个出口,允许程序在任何地方转入子程序或退出子程序。
1.2 调用-返回风格软件体系结构
- 利用调用-返回风格软件体系结构设计的软件系统使用的是分而治之策略,
- 其主要思想是:将一个复杂的大系统分解为一些子系统,以便降低复杂度,并且增加可修改性。
- 这种系统的程序执行顺序通常只由一个单线程控制。
1.2.1 概念
- 每个软件构件都设计为有一个唯一的程序执行起点和一个唯一的程序执行终点;
- 程序从其执行起点开始执行该构件的代码,程序执行结束,将控制返回给程序调用构件,
- 其中,程序构件通常叫做子程序,
- 从一个构件到另外一个构件的控制传递叫做子程序调用。
1.2.2 示意图
1.2.3 组织形式
- 拥有整个软件入口的构件叫做主程序(Main Program),它控制子程序的执行顺序
- 可以被所有构件访问的共享数据被称为全局变量(Global varible)
1.2.4 层次组织
- 调用-返回风格体系结构可以被组织成任何形式。但层次结构的组织形式更清晰
- 层次结构的设计被称为共享数据的主程序-子程序软件体系结构
1.2.4.1 主程序-子程序软件体系结构
- 主程序-子程序软件体系结构在设计上使用层次化的划分方法,该体系结构中使用由编程语言直接支持的单一的控制线程。
- 子程序的结构是明确的,子程序通常组成程序模块。子程序的调用呈现层次状,其正确与否往往取决于其调用的子程序的正确与否。
- 相比于非结构化编程,主程序-子程序软件体系结构能够较好地支持系统的可改变性和可伸缩性等性能,其采用分而治之的策略
1.2.4.2 主程序-子程序软件体系结构示意图
1.2.5 自顶向下的设计方法
- 自顶向下功能化设计方法(结构化程序设计)的设计思想是:系统从功能的角度进行设计,从高层开始,逐步细化为详细设计。
- 该设计从系统要完成的功能需求出发,首先将一个整体问题分为几个子问题,然后再考虑将每个子问题再次划分为几个更小的子问题,依次下去,直到不可再分为止。
- 结构化设计从数据流图(DFD图)开始,然后将数据流图转换为程序结构图。这些图需要用规范的DFD描述,达到系统在建立前有关信息就能被充分理解的目的。
- 在设计时要求严格划分开发阶段,用规范的方法与图表工具精确描述各阶段的工作,每个阶段都以规范的文档资料作为其成果,最终得到满足用户需要的系统。
示例:
一个药品成本计算系统(Medicine Cost Computation)
要计算一种药品的单位成本,要求输入药品的名称(Medicine Name),然后系统输出该药品的单位成本(Medicine Cost per Unit)
- 设计第一层DFD图 (数据流图)
- 设计第二层DFD图
- 设计第三层DFD图
- 将数据流图转换为程序结构图
1.2.6 自顶向下的设计方法的问题
-
功能演化困难
自上而下的方法创建了符合最初需求的较好的软件系统模型。但是当系统改变或者增加新的需求时,功能结构变得越来越笨拙。
由于软件被设计为树形结构,修改与更新通常要求广泛的“剪枝”与“嫁接”,使系统维护变得越来越困难。 -
现实中的系统功能不容易描述
大型交互系统很难从功能方面进行刻画。
很多大型系统没有“顶部”,例如,一个涉及数据查询、数据改变与保持数据一致性的软件系统,如果按照功能化的自顶向下的设计,则该系统可能被设计成为一个基于一个唯一的“虚拟”顶点并且会产生非常复杂的结构。 -
功能化设计丢掉了数据与数据结构。
因为系统分解只突出问题的功能方面,数据结构对问题的影响被丢失了。 -
由功能设计得到的软件产品产生的可复用的代码较少。
每个程序单元的设计都仅仅考虑极为有限的需求,因为这些特定的需求不太可能出现于下个问题中,所以产生的设计与代码没有普遍性与通用性。
1.2.7 结构化设计的优缺点
- 优点
- 逻辑设计与物理设计分离
- 开发过程中形成一套规范化的文档,便于将来修改和维护
- 缺点
- 开发周期长,开发过程复杂
- 系统难于适应环境变化
- 经验表明,较小的程序(小于10万行)适合于结构化开发
1.3 面向对象体系结构
- 结构化编程中的数据可以被程序的任何语句访问,当程序变大时,这种做法使得程序缺陷可能被传到很远,难于维护
- 面向对象设计可以将数据和操作封装起来,使数据的访问受到限制。这种将数据和操作捆绑的方式被称为对象。
- 一个对象是将数据与那些为了访问和维护这些数据的操作(即函数或方法)捆绑在一起的一个实体。对象提供了一些简单易用的、规范化的方法对其数据进行某种操作,而隐瞒了其具体的执行任务的繁琐细节。
- 在面向对象设计中,系统看作由一些对象的集合组成(而不是由函数或者方法组成),消息从一个对象发送到另外一个对象。每个对象都有其相关的功能。
1.3.1 面向对象的特点
- 封装性
- 继承性
- 多态
- 复用和可维护性
- 对象是对现实世界的抽象并且可以管理自己
- 系统功能通过对象服务表示
- 共享数据区域被取消
- 对象可以是分布式的
1.3.2 面向对象的继承机制
- 继承的目的是代码复用
- 继承提供了一个统一的接口,容易实现多态
1.3.3 优缺点
- 优点
- 容易维护:因为一个对象将其内部表示对客户程序隐藏起来,所以可以改变其内部实现而不影响那些客户程序。
- 可复用性好:对象为适合复用的构件。
- 映射现实世界:对于许多软件系统都存在明显的现实世界的实体到系统的对象。
- 容易对一个系统进行剖分:面向对象设计将数据与数据访问、操纵方法绑定在一起形成类,由类产生对象。使得软件设计者将整个问题剖分为一系列的互相交互的对象的集合。
- 缺点
- 面向对象程序占用内存较大。这是因为在程序运行中,每个新被创建的对象都必须占用一块内存,而在面向对象程序中,往往有大量的对象被创建。
- 一个对象要和另外一个对象交互,该对象必须知道另外一个对象的身份,包括对象名、方法名和参数类型等。
1.4 案例分析
设计一个文档更新系统,对符合一定格式的输入文档进行更新,系统的功能描述如下:
- 政治问题,将文档中出现的所有的“Republic of China”改为“Taiwan”
- 两千年(Y2K)问题。对文档中所出现的两位数日期形式“xx”改为“19xx”,如将89改为1989。
- 按行进行字典排序。
文档更新系统的数据变化
文档更新系统-结构化程序设计
结构化程序中包含一个主程序与其他5个函数,Input负责输入整个文件,CorrectPolitical-Error负责修改政治错误,CorrectY2KError负责修改两千年问题,Sort负责排序,Output负责将处理好的文件输出到一个文件中。
文档更新系统-面向对象程序设计
在本设计中,将输入、政治问题、两千年问题、排序、输出功能封装在5个类中,让它们实现一个统一的接口FileUpdateInterface。每个类都实现一个update()方法,以便实现以上的相应功能。
本设计中,所有的数据都被封装在各个类中,每当创建一个类的对象以后,内存都会为该对象开辟出一片内存空间。
1.5 主程序-子程序与面向对象体系结构的相似之处
- 两种设计都属于调用 – 返回风格。
- 主程序-子程序体系结构所产生的程序中,每个软件构件都有一个唯一的程序执行入口和唯一的程序执行出口,并且当一个构件调用另外一个构件时,程序运行控制权将转移给被调用的构件,当被调用构件的代码执行完毕以后,即程序运行至该构件的出口以后,控制被返回给调用的控件。
- 由面向对象体系结构所产生的程序中,当一个对象的方法调用另外一个对象的方法时,被调用对象将接过程序运行控制,当被调用对象的方法运行完以后,控制将交还给调用对象。
1.6 主程序-子程序与面向对象体系结构的区别
结构化设计 | 面向对象设计 | |
---|---|---|
系统分析 | 1. 根据用户需求产生数据流图 2. 根据数据流图生成结构图 3. 使用结构化英语描述算法 4. 通过数据关系分析产生数据关系图 | 1. 建立领域模型类图 2. 根据用户需求产生用例模型 3. 用例实现 4. 建立对象互动图,包括:时序图,协作图及状态图等 |
系统设计 | 1. 数据库设计,包括数据库的正则化 2. 用户图形界面设计 3. 详细设计:函数的参数,算法,返回值 | 1. 具体的数据库设计 2. 设计元素 3. 设计系统软件体系结构 4. 设计类图 5. 设计构件 6. 用户图形界面数据 7. 详细设计,设计类,类中的方法和属性 |
关注点 | 功能,过程 | 对象,数据 |
复用性 | 低 | 高 |
所适合的软件项目 | 定义明确的项目稳定的用户需求 | 需求可能经常改变的大型项目 |
程序结构/元素 | 结构图 元素:函数 | 程序设计类图 元素:类 |
数据/操作封装 | 数据与操作分离 数据外露,所有方法均可访问数据 | 类中封装了数据和操作,只有使用该数据的封装类的相关方法访问数据 |
1.7 练习
- 主程序-子程序体系结构与面向对象体系结构各自使用什么设计方法?两种程序设计最终得到什么图?
答:主程序-子程序体系结构使用自顶向下的功能划分的设计方法,面向对象体系结构使用面向对象的设计方法。
主程序-子程序体系结构最终得到程序结构图,面向对象体系结构最终得到设计类图。
- 试用主程序-子程序结构设计程序:从键盘输入一个2位十进制的月份数(01-12),然后显示出相应的英文缩写名。请画出程序结构图。
解:
2. 数据流风格软件体系结构
数据流系统是一个软件系统,在该系统中,数据的可用性控制计算,过程间的数据有序流动决定了系统的结构。数据的流动方式是明确的。
数据流系统的各软件组件在无数据到达时处于休眠状态,当有数据到达时,该软件组件被激活,开始对数据进行处理。
数据流风格软件体系结构将整个软件系统看作由一系列作用在连续数据集合上的“变换”组成。数据和作用于其上的操作是互相独立的。
软件系统被分解为一些数据处理单元或称为组件,数据流控制数据处理顺序。
数据流风格软件体系结构应用于定义明确的一系列带有有序输入与输出的独立数据变换,数据传输可以是整块的数据传输或者以数据流的形式进行。
在数据流风格体系结构中的组件是可以被重复使用的,且在保证输入与输出接口都不变的情况下,可以独立修改一个组件,而不影响其他的组件。
在实现数据流风格软件体系结构的软件时,需要特别注意组件之间的同步问题。
2.1 数据流风格
- 构件: 数据流构件
- 构件接口是输入端口和输出端口
- 从输入端口读数据,向输出端口写数据
- 计算模型:从入口读数,计算,然后写到出口
- 连接件:数据流
- 单向
- 通常是异步的,有缓冲
- 接口是reader和writer
- 计算模型: 把数据从writer转向reader
控制流与数据流的比较:
- 控制流 (典型例子 程序系统)
- 主要问题是控制点怎样在程序或系统之间移动
- 数据可能跟着控制走,但是并不起推动系统运转的作用
- 关注的核心是计算顺序
- 数据流
- 主要问题是数据怎样在运算单元之间流动
- 数据到了,控制(计算)单元便开始工作
- 关注数据是否可用,转换,……
数据流风格三种例子
- Batch Sequential(批处理)
- Pipe-and-Filter(管道-过滤器)
- Process Control(控制)
2.2 顺序批处理软件体系结构
特点:
- 每个处理程序模块都是互为独立的程序。
- 只有上一步程序彻底完成了,下一步程序才能开始。
- 数据作为一个整体进行传输。
- 因为以上的特点,所以不必对其组件进行同步处理。
- 因为几个组件只能按照顺序运行,而不能同步运行,所以性能可能比那些能按照几个组件同时运行的程序要差一些。
- 使用顺序批处理结构设计的软件不适用于要求对数据进行实时处理的系统。
示例:
考虑设计一个数字图像处理软件。
该软件应该有一个用户图形界面。并包含一些可以随时添加的过滤器(Filter),例如图像模糊(Blurring)、图像锐化(Sharpening)、图像变亮(Brightening)、发现图像边界(EdgeDetector)等,每个过滤器完成一项特定的图像处理功能。多个过滤器串联在一起可以完成一些比较复杂的功能。可以使用顺序批处理体系结构设计该系统。
Blurring对象负责对图像进行平滑滤波,然后将结果文件存入存储介质T2,同时将内容显示到用户图形界面上;
Sharpening对象对图像进行锐化滤波,然后将结果文件存入存储介质T3,同时将内容显示到用户图形界面上;
Brightening对象将图像进行亮化处理,然后将结果文件存入存储介质T4,同时将内容显示到用户图形界面上;
EdgeDetector对象对图像进行发现边界的处理,然后将结果文件存入存储介质T5,同时将内容显示到用户图形界面上。
其设计类图如图
其中ImagePro从GUI为用户图形界面,PipeLineBuilder类负责根据用户输入的要选择的图形处理项目,从4个图像处理类中选择生成相应的图像处理类。
2.3 管道与过滤器软件体系结构
管道-过滤器体系结构是数据流风格体系结构的一个子类型。该体系结构在形式上与顺序批处理结构相似,但是实际上它们却有本质的区别。
在管道-过滤器软件体系结构中,每个组件都有一组输入和输出,组件读入输入数据流,经过数据处理,然后产生输出数据流。这个过程通常通过对输入流数据进行增量式的"变换"或者称为"计算"来完成,所以在输入被完全消费之前,输出便产生了。因此,这里的组件被称为过滤器,这种风格的连接件就像是数据流传输的管道,将一个过滤器的输出传到另一过滤器的输入。
2.3.1 过滤器
一个过滤器由Input Port、Filter与Output Port三部分组成。Input Port部分负责存储待处理的数据,Filter负责处理数据,Output Port负责存储已经处理完的数据。
过滤器必须是独立的主体,无须知道输入/出管道的存在。但要对输入管道和输入数据流进行限制。
2.3.2 管道
管道的责任是运送数据。管道由输入流(Input Stream)与输出流(Output Stream)组成,管道组件Pipe负责将数据由Input Stream传送到Output Stream。
作用:在过滤器之间传送数据
- 单向流
- 可能具有缓冲区
- 管道形成传输图
不同的管道中流动的数据流,具有不同的数据格式,原因:数据在流过每一个过滤器时,被过滤器进行了丰富、精练、转换、融合、分解等操作,因而发生了变化。
2.3.3 过滤器类型
过滤器类型分为主动型过滤器(Active Filter)和被动型过滤器(Passive Filter)。在具体的应用中,根据不同的问题,可以选择使用不同类型的过滤器。
- 主动型过滤器的功能包括拉入数据,并且推出经过变换以后的数据。此时管道为被动的,并且为了拉和推提供了读/写机制。
- 被动型过滤器将推动数据的责任交给了与其相连的管道。这样的管道应该具有将数据从上一个过滤器拉出,并且推到下一个过滤器的能力。此时,过滤器必须提供读/写机制。
管道-过滤器软件体系具有如下优点:
- 并发性:对于海量数据处理问题,可以提供高通量的产出。
- 可复用性:封装了过滤器,使得过滤器可以被非常容易地插入与替换。
管道过滤器构成的网络,其输出的正确性与过滤器的递增处理顺序无关。
注意:
将每个过滤器的输入/输出限制为单一的,则管道-过滤器退化为顺序批处理系统(Batch sequential)。
2.3.4 案例分析:设计遗产文件更新系统
对符合一定格式的输入旧文档进行更新。系统分为几个功能:(1)输入旧文档。(2)解决两千年问题。(3)对每个处理完的行添加注释,例如处理日期等。(4)将修正以后的文档分别写入文档new.txt并输出到屏幕。
解析:
2.3.5 优缺点
-
优点
- 使得软构件具有良好的隐蔽性和高内聚、低耦合的特点;
- 允许设计者将整个系统的输入/输出行为看成是多个过滤器的行为的简单合成;
- 支持软件复用。只要提供适合在两个过滤器之间传送的数据,任何两个过滤器都可被连接起来;
- 系统维护和增强系统性能简单。新的过滤器可以添加到现有系统中来;旧的可以被改进的过滤器替换掉;
- 允许对一些如吞吐量、死锁等属性的分析
- 支持并行执行。
- 由于每个构件的行为不受其他构件的影响,整个系统的行为易于理解。
- 支持功能模块的复用:
- 只要提供适合在两个过滤器之间传送的数据,任何两个过滤器都可被连接起来;
- 具有较强的可维护性和可扩展性。
- 支持特殊的性能分析:
- 因为系统是通过独立的过滤器组合,系统具有清晰的拓扑结构,因而容易进行特殊性能方面的分析,吞吐量、死锁、计算正确性等。
- 支持并发执行:
- 每个过滤器是作为一个单独的任务完成,因此可与其它任务并行执行
- 从而增加了系统的灵活性,使提高运行效率成为可能,尤其是网络环境下的管道。
-
缺点
- 通常导致进程成为批处理的结构。
- 因为虽然过滤器可增量式地处理数据,但它们是独立的,所以设计者必须将每个过滤器看成一个完整的从输入到输出的转换;
- 不适合于需要共享大量数据的应用设计。
- 不适合处理交互的应用。当需要增量地显示改变时,这个问题尤为严重;
- 过滤器设计的复杂性:
- 因为在数据传输上没有通用的标准,每个过滤器都增加了解析和合成数据的工作,为保证过滤器的正确性,必须对数据的句法和语义进行分析,这样就增加了编写过滤器的复杂性,并导致了系统性能下降。
- 并行运行获得高效率往往行不通:
- 独立过滤器之间的数据传送的效率很低,尤其在网络传送时。
- 过滤器通常在消耗了所有输入之后才产生输出;
- 在单处理器的机器上进程的切换代价是很高的。
- 通过管道对过滤器的同步控制可导致频繁启动和停止过滤器工作。
- 通常导致进程成为批处理的结构。
2.3.6 顺序批处理系统与管道-过滤器软件体系结构的比较
- 相似点
- 把任务分解为一系列固定顺序的计算单元。
- 彼此之间只通过数据传递交互。
- 处理模块的互相独立性。在批处理系统与管道-过滤器体系结构中,处理过程是互相独立的,即在批处理系统体系结构中,每个处理过程都不调用其他处理过程;在管道-过滤器体系结构中,每个过滤器都不调用其他过滤器。
- 不同点
- 数据处理方式不同。在顺序批处理系统中,只有上一步程序彻底完成了,下一步程序才能开始进行,数据作为一个块状整体传输。通常是每个中间步骤都要有中间存储。各个处理过程不是同时工作,只有前面相邻的处理过程完成时,后面的过程才能开始工作。在管道-过滤器体系结构中,过滤器渐进式地以流对流的方式变换数据,各个过滤器在同时工作。
2.4 过程控制的体系结构
开环控制:
被控对象的输出对控制器的输出没有影响。如果过程被充分定义,而且操作完全可以重复,过程就可以在无监督的情况下运行,这样的系统被称为开环系统。
闭环控制:
被控对象的输出会反送回来影响控制器的输出,形成多个闭环。
过程控制系统:
所谓对某个过程进行控制,是指设法使该控制过程的功能或特性有效达到所期望的目标。目标可以是满足所规定的各种性能特征,也可以是在一定限制条件下,使某个代表性能的量达到或者接近最佳。
2.5 练习
- 下列两种情形中哪种适合使用顺序批处理体系结构
a、一个需要对数据进行实时处理的银行业务系统。
b、一个需要周期性更新的人口普查系统。
解析:b
- 使用管道-过滤器体系结构设计与实现一个处理职员收入信息的软件。程序应该按照如下方式对输入文件employee.txt进行处理:(1)按照职员工资金额对文件内容进行排序。(2)找出年薪在120000元以上的所有职员。(3)计算年薪在120000元以上的职员的个人所得税,税率为30%。(4)打印出年薪在120000以上的职员的税收信息。
a、画出设计的(管道图)逻辑图
b、画出设计类图,包括所有的类的设计与方法。
c、描述每个方法的功能。
解析:
注:题C,考试的时候要写清楚一下。
3、使用管道-过滤器体系结构设计以下问题。要求:在设计的在线销售系统中,新的订单以消息的形式送达企业。该消息被加密,包含数字证书形式的认证信息,并且可能有重复发送消息的情况发生。系统功能包括:(1)输入客户订单消息。(2)对该消息进行解密。(3)检查认证信息。(4)检查是否有重复发送的消息,如果被复制的消息发生了,则取消重复的订单,仅保留一份订单。要求:
a、画出设计的(管道图)逻辑图
b、画出设计类图,包括所有的类的设计与方法。
c、描述每个方法的功能。
解析:
注:题C,考试的时候要写清楚一下。
3. 基于事件的软件体系结构
事件系统中的组件的注册、广播、调用机制:
- 系统中的每个组件可以注册一种或多种事件(对该事件感兴趣)。
- 当一个组件要发布事件时,该组件可以广播一个或者多个事件到事件空间。
- 每当一个事件被广播了,系统将负责自动调用那些已经注册了该事件(对该事件感兴趣)的组件或者过程,被调用的组件(对象、过程)将运行。事件发布组件不知道被调用的组件将要做什么。
事件系统的连接机制:
- 连接件:事件—过程绑定。
- 过程<事件处理器,事件的接收和处理方>:向特定的事件进行注册
- 构件<事件源>:发布事件
- 当某些事件被发布时,向其注册的过程被隐式调用,调用的次序是不确定的。
事件系统的调度策略:
- 带有分离的派遣模块的事件管理器
- 没有中心派遣模块的事件管理器
3.1 事件派遣模块
事件派遣模块的功能:
负责接收到来的事件并派遣它们到其他模块。
派遣器决定派遣方式,有两种派遣方式:
- 广播式:派遣模块将事件广播到所有的模块,但只有感兴趣的模块才去取事件,并触发自身的行为;
- 选择广播式:派遣模块将事件送到那些已经注册了的模块中。
选择广播式的两种策略:
1.Point-to-Point(点对点模式):基于消息队列
2.Publish-Subscribe(发布-订阅模式)
3.1.1 点对点的选择广播式:消息队列
- 系统安装并配置一个队列管理器,并定义一个命名的消息队列
- 某个应用向消息队列注册,以监听并处理被放置在队列里的事件
- 其他的应用连接到该队列,并向其中发布事件
- 队列管理器存储这些消息,直到接收端的应用连接到队列,取回这些消息并加以处理。
- 消息只能被唯一的消费者所消费,消费之后立即从队列中删除。
3.1.2 发布-订阅的选择广播式
- 事件发布者向“主题”发布事件,订阅者向“主题”订阅事件。
- 一个事件可以被多个订阅者消费;
- 事件在发送给订阅者之后,并不会马上从topic中删除,topic会在事件过期之后自动将其删除。
3.2 无独立调度模块的事件系统——观察者模式
这种模式称为“被观察者/观察者”,每一个模块都允许其他模块向自己所发送的某些消息表明兴趣。当某一模块发出某一事件时,它自动将这些事件发布给那些曾经向自己注册过此事件的模块。
观察者模式的各组成部分说明如下:
- Observable:被观察者接口,声明了三个应该实现的方法。在简单的情况下,**register(obs:Observer)**方法负责将参数中的观察者注册到Subject对象,在Subject对象中保持一个具体的观察者列表,用于记载所有的观察者。**unRegister(obs:Observer)**方法用于在列表中删除参数中的观察者对象。**notify()**方法用于通知观察者subject状态的改变。
- Subject:具体的观察者要依赖的对象,它要实现Observable的所有方法。在Subject中的**getState()**方法可以被ConcreteObserver调用,以便得到最新的状态。
- Observer:观察者接口,代表依赖对象。观察者可以有多个。
- ConcreteObserver:代表具体的观察者对象。
观察者模式的工作原理如下:
- 被观察者保持一个数据结构,如Java ArrayList,用于记载动态添加的观察者。
- 对被观察者状态感兴趣的对象(观察者),应该调用被观察者的Register方法将自己注册为它的一个观察者。
- 每当被观察者的状态发生改变的时候,它将使用方法notify()通知已经注册的观察者。
- 当接到通知以后,每个观察者都将查询被观察者的状态,以便保持状态同步。根据新的状态,观察者将决定做一些图标更新或者其他相关的操作。
- 观察者将提供一个接收被观察者通知的接口,例如synchronizeState(),被观察者在方法notify()中可以调用该接口。
3.2.1 案例
模拟锅炉的温度显示情况。假如被观察者代表锅炉,用TemperatureGUI表示。为了以不同的方法显示温度值,设计了几个观察者,摄氏温度图形显示界面CelsiusGUI对象、华氏温度图形显示界面FahrenheitGUI对象和凯文温度显示界面KelvinGUI对象,共同观察被观察者TemperatureGUI对象。
当用户在TemperatureGUI图形界面中输入摄氏、华氏或者凯文温度的时候,相应地,根据温度换算的情况,几个温度观察者界面将分别显示摄氏、华氏或者凯文温度,并且还显示温度颜色,即用不同的颜色表示不同的温度。使用观察者模式,进行设计。
解析:
3.3 练习
- 在上面的案例中,当调用Observable类的notifyObserver之前,还应该同时调用什么方法?
解析:setChanged()
- 设计一个控制金鱼缸水质、水温与水位高度的软件系统。基本需求:该程序用于自动控制金鱼缸中的水质、水温与水位高度。系统硬件包含鱼缸、化学传感器、水温传感器与水位传感器。当化学传感器的读数超过某种范围时,鱼缸需要排除部分废水,同时补充新鲜的水;当水温传感器读数低于某温度,或者超过某温度值时,需要开启加热设备或者冷却设备调整水温;当水位读数高于或低于特定高度时,需要开启排水设备,排除部分水或者添加新鲜的水。
要求使用观察者模式设计该软件系统。具体要求:
①画出设计类图。
②解释设计的控制程序的风格,说明类图中各软件组件之间的关系及各软件组件所包含的功能。
解析:
4. 层次软件体系结构
层次系统组织成一个层次结构,每一层为上层服务,并作为下层客户。层次体系结构如图所示:
层与层之间的调用为单向的,即第n层中的类可以调用第n-1层中的类的方法,但是在第n-1层中的类不能调用第n层中方法。另外,也不允许隔层调用,即不允许第n层越过第n-1层而直接调用第n-2层。在实际应用中,第0层一般包含针对来自于硬件输入信息的处理过程、函数或者方法。连接件通过决定层间如何交互的协议来定义,拓扑约束包括对相邻层间交互的约束。
层次软件体系结构还可以形象地被描述为一个鸡蛋的形状,其内层表示较为低的层,外层为较高的层。在严格的层次结构中,除了其相邻的外层以外,内层提供的功能不能被所有其他外层访问。但有时为了某种特殊目的,例如提高性能的考虑,某些内层函数不得不被输送到外层供外层使用。
层次体系结构包括但不限于下述典型的应用领域:
- 层次通信协议。
- 数据库系统领域。
- 操作系统领域。
层次系统的基本构件:各层次内部包含的构件
连接件:层间的交互协议
拓扑结构:分层
拓扑约束:对相邻层间交互的约束
这种风格支持基于可增加抽象层的设计,允许将一个复杂问题分解成一个增量步骤序列的实现。
不同的层次处于不同的抽象级别:
- 越靠近底层(硬件与OS),抽象级别越高,越通用;
- 越靠近顶层(用户),抽象级别越低,越具体;
由于每一层最多只影响两层,同时只要给相邻层提供相同的接口,允许每层用不同的方法实现,同样为软件复用提供了强大的支持。
某一层中的构件只能与同一级别中的对等实体或较低级别中的构件交互,这有助于减少不同级别中的构件之间的依赖性。
4.1 分层模式
有两种通用的分层方法:
- 严格分层(Strict System Layering)
- 松散分层(Loosely System Layering)
4.1.1 严格分层
系统要求严格遵循分层原则,限制一层中的构件只能与对等实体以及与它紧邻的下面一层进行交互。第 N 层只能与第 N-1 和N+1层中的构件进行交互,第 N-1 层只能与第 N和N-2层进行交互,依次类推。
优点:修改时的简单性
当某一层被加入或被替换时,它的影响范围很有限,容易管理
缺点:过度的严格分层 效率低下
例如:网络系统中使用严格分层,但导致效率低下
因此在很多实际系统里,并不遵循严格分层的原则
4.1.2 松散分层
松散的分层应用程序放宽了此限制,它允许构件与位于它下面的任意层中的组件进行交互第N 层不仅可以与第 N-1 层交互,而且可以与第 N-2层和第 N-3 层交互。
优点:
松散方法可以改善效率,因为系统不必将简单调用从一层转发到下一层。
缺点:
松散方法在层之间不提供相同的隔离级别,这使得在不影响较高层的情况下换出较低层变得更困难。
4.2 交互方式
针对分层系统中各层次之间如何交互,分为以下两种基本的交互方式:
- 由上而下的交互方式 (top-down triggering)
- 由下而上的交互方式 (bottom-up triggering)
4.2.1 由上而下模式
在由上而下模式中,外部实体与系统中的最高层交互。最高层使用较低级别层的一个或多个服务。反过来,每个较低级别都使用它下面的层,直到到达最低层。
特点
- 一个传入调用会导致多个传出调用。
例如:第 N 层上的服务 1 的调用说明了这种情况。 - 可能会使用松散的分层方法。
服务 2 的实现绕过了所有中间层而直接调用第 1 层。
例如:数据维护应用程序绕过任何中间业务逻辑层而直接访问数据访问层的表示层。 - 顶层服务的调用并不一定会调用所有层。
例如:服务 1 到操作 2 顺序。
当较高级别可以处理自身中的调用,或者缓存了较早的某个请求的结果时,就会发生这种情况。
4.2.2 由下而上模式
在由下而上模式中,外部实体与系统中的最底层交互,通常用来监视某些底层系统的状态变化。当被监控对象状态发生改变时,触发系统最底层的某些服务;每个较低级别回调它上面的层的服务,直到到达最顶层;在此方案中,客户端只能使用最底层的一组服务,而无法直接了解任何较高的层。
4.2.3 区别
在由上而下方案中,较高层直接调用较低层,因此高层依赖于低层。
在由下而上方案中,较低层通过事件(event)、回调和委派(callbackdelegate)来与较高层通信。
目的:防止较低层依赖于较高层。
由上而下的信息和控制通常被描述成“请求”;
由下而上的方式被描述为“通知”。
4.3 双向分层
在某些网络/通讯系统里,信息必须在两个方向都可以传递
- 发送端系统中:高层 =>低层
- 发送端与接收端系统在最底层的交互
- 接收端系统中:低层 =>高层
4.4 分层风格 VS 主程序-子过程风格:二者的不同
-
主程序-子过程风格:各层次模块的功能具有同样的类型
-
分层风格:各层模块具有不同类型的功能
4.5 优缺点
优点:
- 层次体系结构支持基于随着层次的增加而不断抽象的设计。这使得实现者能将一个复杂问题分解成一系列从初等的与硬件相关的功能到越来越抽象的可以被用户使用的高级功能。
- 层次体系结构支持更新。每层最多与两个层交互,即该层的上层与下层。因此,在确保接口不变的前提下,可以单独修改或更换某一层的某些组件而不影响其他层。
- 层次体系结构支持复用。相同的层可以有不同的实现,只要这些不同的实现支持与之相邻的层的相同接口;使用标准的层次接口,每一层都可以由不同的软件开发团队来完成;一个单独的层可以被其他软件复用。
缺点:
- 不是所有的系统都容易被组织成层次结构。
- 有时即便一个系统可以从逻辑上被组织成一个层次结构,但是出于性能方面的考虑,可能要求层次结构中的逻辑上的较高层次与较低层次之间有比较紧密的耦合,从而迫使软件设计实现者考虑跨层调用,而这是违反层次架构原理的。
- 正确的层次抽象往往可能有困难。
4.6 练习
- 指出层次软件体系结构的三个典型应用。
答:层次通信协议,数据库系统领域,操作系统领域
5. MVC软件体系结构
MVC体系结构将一个互动的应用分为三部分:Model、View、Controller。Model包含核心功能与数据,View为用户显示信息,Controller处理用户输入。
- 根据责任分离与增加可扩展性的原则,Model应该被设计成独立于特定的输入行为和输出表示的程序。
- View模块将模型中的数据显示给用户。而因为相同的数据可以有不同形式的显示方法,所以一个Model可以有很多个View。
- 每个View可以拥有与之关联的Controller组件。
5.1 MVC模型各部分功能
模型的责任
- 从数据库取出数据,并且赋予数据变量
- 负责业务逻辑实现
- 负责数据验证,然后将数据存入数据库
视图的责任
- 获取用户输入
- 向controller发送处理请求
- 接收来自Controller的反馈并将model的处理结果显示给用户
控制器的责任
- 接收来自客户的请求
- 调用model业务逻辑方法
- 调用View显示执行结果
5.2 MVC的 改变–传播机制
如果用户通过一个View的Controller改变了Model,所有其他的View必须反映这个改变。
当时数据发生变化的时候,Model负责通知所有的View,数据已经改变。View可以查询Model中的数据,以发现改变,并且更新数据。
这种改变-传播机制保证了用户界面的一致性。
5.3 观察者模式的MVC体系结构
Controller从用户图形界面接收用户输入,然后再根据用户输入类型,调用Model的相应业务功能。然后在Model类的withdraw()方法中,访问数据库的表进行相应的处理。
由于采用了观察者机制,作为观察者的View的自动更新可由Model中的通知方法notifyObservers()执行,然后在View的update()方法中反过来查询到底是什么数据发生了变化,从而更新视图自身。
5.4 优缺点
优点:
- 对于同一个模型,可以有不同的视图与控制器,以便提供给用户不同类型的用户图形界面;
- 改变 - 传播机制保证了模型在改变的同时自动刷新所有的视图,所有的视图都同时实时地反映了模型的现有状态;
- MVC体系结构的设计使得改变用户的图形界面变得非常容易,MVC结构非常适合业务逻辑较少改变,而用户图形界面经常要改变的应用;
- 由于全部的核心数据与核心功能都包含在模型(Model)中,因此很容易对核心的应用进行测试。
缺点:
- 不适合小型,中等规模的应用程序,花费大量时间将MVC应用到规模并不是很大的应用程序通常会得不偿失;
- 对于简单的界面,严格遵循MVC,使模型、视图与控制器分离,会增加结构的复杂性,并可能产生过多的更新操作,降低运行效率;
- 视图与控制器是相互分离,但却是联系紧密的部件,视图没有控制器的存在,其应用是很有限的,反之亦然,这样就妨碍了他们的独立重用;
- 依据模型操作接口的不同,视图可能需要多次调用才能获得足够的显示数据。对未变化数据的不必要的频繁访问,也将损害操作性能。
5.5 三层体系结构与MVC 软件体系结构的比较
在形式上,三层体系结构类似于MVC 体系结构,都是由三部分组成的但是实际上是不同的。
相似之处如下:
- 三层体系结构的显示与MVC 体系结构的View 类似。
- 三层体系结构的应用层与MVC体系结构的Model类似。
区别之处如下:
- 各个模块之间的调用关系不同。
三层体系结构的一个根本原则是显示层不允许直接调用永久数据存储层。在三层体系结构中,所有的客户端与永久数据存储层的通信必须穿过中间层。若显示层请求查询数据库,该层不能直接越过应用层直接调用永久数据存储层的代码,必须调用应用层,然后再由应用层的相关方法转而调用永久数据存储层。不允许有相反方向的调用。因此,三层的体系结构是线性的。 - 对数据库的访问方式不同。
三层体系结构指定一个永久数据访问层,所有对数据库的咨询均由此层承担;MVC体系结构设有指定专门的数据库访问模块,一般情况下是由Model直楼访问数据库。但是也没有排除Controller中直接访问数据库的可能。 - MVC 体系结构中有一个 专门的Controller 模块,而层次体系结构中通常没有这样的专门模块。
很多设计者在层次体系结构中的应用层里面可以单独地指定一个类似的控制组件。
考虑到采用观察者机制更新图形界面的效率,在3层架构中,应用层与表示层之间使用观察者模式必然会导致应用层对显示层的调用(notifyObservers()),这违反了层次架构的原则,但有时候是值得的。
5.6 练习
- 在带有观察者机制的MVC体系结构中,将观察者类中的更新方法update(Observable e)的参数类型设为Observable,这样做的好处是什么?
答:将观察者类中的更新方法update(Observable e)的参数类型设为Observable,在被观察者对象发生变化时,它会调用0bservable的 notifyObservers()方法,此方法调用所有的具体观察者的update()方法,从而使所有的观察者都被通知更新自己。
- 设计一个火车售票系统,需要有用户图形输入界面,包括车票的出发时间、价格、车次以及当前剩余车票数的显示界面。要求:
1)车票需要显示以下信息:出发时间、价格、车次、当前剩余车票数;
2)剩余票数的显示必须立即反映票数的变化;
3)用户界面易于改变,甚至在运行时改变。
采用MVC体系结构(使用观察者机制)设计该题,用户输入界面和显示视图独立显示。
解:
第七章 基于网络的软件体系结构
- 客户端-服务器软件体系结构
- P2P软件体系结构
- 网格计算软件体系结构
- SOA软件体系结构与Web Service
1. 客户端-服务器软件体系结构
基本概念
- C/S软件体系结构是基于资源不对等,且为实现共享而提出来的,是20世纪90年代成熟起来的技术,
- C/S体系结构定义了工作站如何与服务器相连,以实现数据和应用分布到多个处理机上。
- C/S体系结构有三个主要组成部分:服务器、客户应用程序、网络。
任务分配
服务器(后端):与客户机通讯的接口、业务逻辑、数据管理。
服务器任务主要集中于:
- 数据库安全性的要求;
- 数据库访问并发性的控制;
- 数据库前端的客户应用程序的全局数据完整性规则
- 数据库的备份与恢复。
客户应用程序(前端):业务逻辑、与服务器通讯的接口。
客户端主要任务:
- 提供用户与数据库交互的界面;
- 向数据库服务器提交用户请求并接收来自数据库服务器的信息;
- 利用客户应用程序对存在于客户端的数据执行应用逻辑要求。
发展历史
随着时间的推移,客户端-服务器系统也经历了一系列的变化,从早期的两层的客户端-服务器体系结构发展到三层体系结构,再到目前的多层体系结构。目前,多层的客户端-服务器体系结构已经成为Web开发的主要架构。
现在,当人们提到客户端-服务器体系结构的时候,通常指的是三层的客户端-服务器体系结构。
客户端-服务器软件体系结构是一个多样性的、基于消息的模块基础结构。其目的是改善可用性(Usability)、灵活性(Flexibility)、互操作性(Interoperability)与可伸缩性(Scalability)。
客户端被定义为是一个服务请求软件,服务器被定义为一个服务提供软件,客户端与服务器互相通信。
1.1 一层客户端-服务器软件体系结构
一层客户端-服务器软件体系结构是在20世纪70年代开始使用的基于大型机的体系结构。
用户分时使用主机,使用终端通过键盘输入数据到主机。其特点是计算机体积庞大、价格昂贵、维护成本高,等等。典型的大型机包括IBM的Unisys等。
一层的客户端-服务器软件体系结构的明显缺点:
- 所有的业务逻辑与数据文件均在主机上,实际上没有客户端程序,因此实现起来价格昂贵。
- 另外,因为技术限制,当时的大型机基本上没有图形界面,而只能使用键盘输入。由于大型机需要分时操作,因此只能供很少的客户使用。
随着时间的推移,企业中需要使用计算机的用户越来越多。为了适应新的需要,公司开始考虑将大型机的应用分成客户端与服务器两部分,这就产生了将要介绍的文件共享软件体系结构。
1.2 文件共享软件体系结构
较早的个人计算机网络基于文件共享原理,所有的数据都集中存储在一个文件服务器中,供授权用户访问。
工作原理如下:
- 客户端发送文件请求,该请求被发送到文件服务器。
- 文件服务器的文件管理系统帮助找到所需要文件。
- 客户端下载所需要的文件。
- 客户端更新文件,例如写入新的商业信息等。
- 客户端将更新以后的文件发送给文件服务器。
文件共享软件体系结构的缺点如下:
- 该软件体系结构只有在共享用户使用率比较低,并且数据转移量也较低的情况下才能有效地工作,即该体系结构只能支持少量的用户。
- 业务逻辑完全在客户端,所以要修改业务逻辑时必须要修改每个客户端。
随着网络应用的发展和网络用户的迅猛增长,以及桌面GUI的出现,使得文件共享系统很快过时。通过将文件服务器替换为真实的数据库服务器,并通过用回答关系型数据库管理系统查询的方式回答客户端的请求,极大地减少了网络信息流通量,产生了两层客户端-服务器软件体系结构。
1.3 两层客户端-服务器软件体系结构
在两层客户端-服务器体系结构中,通常使用SQL实现客户端和服务器之间的通信,其中,服务器可能支持存储过程和触发器,这就意味着服务器可以被编程实现业务逻辑,而事实上,业务逻辑在服务器上运行要比在客户端上运行更合适。所以该体系结构是一个更有效的整体系统。两层客户端-服务器体系结构的结构图如图所示:
用户界面位于客户机
数据库管理服务位于服务器端,通常是存储过程/触发器的形式
业务处理过程—即业务逻辑,被分解为客户机与服务器两部分
基本构件:
- 数据库服务器
- 客户端应用程序
连接件:
- 经由网络的调用-返回机制或事件机制。
- 客户机<–>服务器:客户机向服务器发送请求,并接收返回结果。
在两层客户端-服务器体系结构的内容中,
- 第一层包含用户图形界面、应用程序和部分业务逻辑;
- 第二层包含部分业务逻辑、遗产数据与其他资源管理系统、数据库管理系统与共享资源等。
两层客户端-服务器的工作原理如下:
- 客户端发送SQL语句进行一项数据查询,或者要求更新数据库。
- 服务器端数据库管理系统可以协助用户查询,并且将查询结果返回给客户端;或者更新数据库,例如修改一个表中某一个域的值,或者写入新的商业记录。
业务逻辑的划分比重:在客户端多一些还是在服务器多一些?
- 胖客户端:客户端执行大部分的数据处理操作
- 瘦客户端:客户端具有很少或没有业务逻辑
适用场合: - 两层C/S架构通常被用在那些管理与操作不太复杂的非实时的信息处理系统。
- 适合于轻量级事务 ——客户机对服务器的请求少,数据传输量少。
- 当业务逻辑较少变化以及用户数少于100时,两层C/S架构的性能较好
两层客户端-服务器体系结构的缺点如下:
- 它是单一服务器且以局域网为中心的,所以难以扩展至大型企业广域网或因特网。
- 它受限于供应商,程序的升级维护必须由供应商重新开发扩展。
- 数据库被厂商锁定,因为用户的GUI代码直接与数据库服务器绑定,依赖于一个特定厂商的技术将会使用户更换其他产品很困难。
- 当配置到远程环境的时候,两层客户端-服务器结构管理起来比较困难。尤其是对于胖客户端的情况,就更难以管理。
- 在软件上常常呈现出胖客户端,用户必须在客户端安装特定的客户端应用程序,而且当越来越多的企业的业务逻辑写在客户端应用程序中的时候,程序维护变得越来越困难。程序升级需要每个客户端都要安装新的客户端应用程序,同时,对于程序开发商来说,程序模块的重用性差,各个模块相对独立。
- 很难管理大量的客户机。
基于以上原因,传统的客户端-服务器模式已经不能适应发展的需要,随着网络技术的普及和用户需求的进一步提高,三层客户端-服务器模式应运而生。
1.4 三层客户端-服务器软件体系结构
为了克服两层软件体系结构的局限性,人们在用户系统接口客户环境和数据库管理服务器环境之间,引入一个中间层。带有这样的中间层的体系结构被称为三层客户端-服务器体系结构(3-Tier Client/Server),如图所示。
三层客户端-服务器体系结构的内容为:
- 第一层:包括运行在客户端操作系统中的图形用户界面或者是网页浏览器。
- 第二层:通常包括所有的业务逻辑处理程序,也可能包括为浏览器生成网页内容的图形用户界面处理程序。
- 第三层:包括数据库管理系统、遗产数据库管理程序与数据库。
优点:
- 允许合理地划分三层结构的功能,使之在逻辑上保持相对独立性,能提高系统和软件的可维护性和可扩展性。
- 允许更灵活有效地选用相应的平台和硬件系统,使之在处理负荷能力上与处理特性上分别适应于结构清晰的三层;并且这些平台和各个组成部分可以具有良好的可升级性和开放性。
- 应用的各层可以并行开发,可以选择各自最适合的开发语言。
- 用功能层有效地隔离开表示层与数据层,未授权的用户难以绕过功能层而利用数据库工具或黑客手段去非法地访问数据层,为严格的安全管理奠定了坚实的基础。
- 在用户数目较多的情况下,三层C/S结构将极大改善性能与灵活性(通常可支持数百个用户)。
注意的问题:
- 三层C/S结构各层间的通信效率若不高,即使分配给各层的硬件能力很强,其作为整体来说也达不到所要求的性能。
- 设计时必须慎重考虑三层间的通信方法、通信频度及数据量。这和提高各层的独立性一样是三层C/S结构的关键问题,也是层次风格的固有缺点。
1.5 三层 VS 两层
两层客户端-服务器体系结构与三层客户端-服务器体系结构主要有以下方面的不同:
- 在系统管理方面,两层体系结构复杂,需要管理在客户端的许多业务逻辑,而三层体系结构比较简单,应用可以在服务器端使用系统管理工具进行集中管理。
- 在数据封装方面,两层体系结构的客户端与服务器之间的交互使用SQL语句,数据表示外露;三层结构则较好,通过客户端调用服务或者方法来完成。
- 在重复应用方面,因为仅仅是单一的客户端,所以两层体系结构不容易做到复用;而三层体系结构在复用方面表现良好,可以复用服务与对象。
- 在遗产应用集成方面,对于两层的客户端-服务器体系结构,因为仅仅是有限的客户通信链接管理,所以进行遗产应用集成很困难;而对于三层客户端-服务器体系结构来讲,可以利用封装服务与对象的方式,通过网关、网络连接器、路由器进行遗产应用集成。
- 在互联网支持方面,在两层客户端-服务器体系结构中,由于网络带宽限制了下载胖客户端,所以互联网支持不好;而三层客户端-服务器体系结构由于在客户端往往只有网络浏览器,所以该方面表现优良。
- 在多数据库支持方面,在两层客户端-服务器体系结构中,因为数据库被厂商锁定,所以几乎不可能使用多数据库;而在三层结构中,一个商业交易可以使用几个数据库。
1.6 三层层次体系结构与三层客户端-服务器软件体系结构的区别
三层层次体系结构与三层客户端-服务器软件体系结构的主要区别是:
- 在通常的层次体系结构中所涉及的层次指的是逻辑层,而三层客户端-服务器体系结构中所涉及的层是从物理方面考虑的层。即客户端运行在PC上,服务层被部署在应用服务器上,数据库层包含数据库与数据库管理系统软件,被部署在数据库服务器上。
1.7 练习
- 用文字叙述层次体系结构与客户端-服务器体系结构的区别。
答:在通常的层次体系结构中所涉及的层次指的是逻辑层,而三层客户端-服务器体系结构中所涉及的层是从物理方面考虑的层。即客户端运行在PC上,服务层被部署在应用服务器上,数据库层被部署在数据库服务器上。
- 三层客户端-服务器体系结构与两层客户端-服务器体系结构相比,明显的优点有哪些?
答:
- 在系统管理方面,三层体系结构比较简单,应用可以在服务器端使用系统管理工具进行集中管理。
- 在数据封装方面,三层结构则较好,通过客户端调用服务或者方法来完成。
- 在重复应用方面,三层体系结构在复用方面表现良好,可以复用服务与对象。
- 在遗产应用集成方面,对于三层客户端-服务器体系结构来讲,可以利用封装服务与对象的方式,通过网关、网络连接器、路由器进行遗产应用集成。
- 在互联网支持方面,三层客户端-服务器体系结构由于在客户端往往只有网络浏览器,所以该方面表现优良。
- 在多数据库支持方面,在三层结构中,一个商业交易可以使用几个数据库。
2. P2P软件体系结构
- P2P体系结构是一种非集中架构,即在网络中没有服务器或是客户端的概念。
- 在P2P体系结构模型中,网络中的每一个结点都被认为是一个对等点,它们拥有相同的地位,
- 任何一个结点都可以请求服务和提供服务,也就是说每个结点都是客户端,也是服务器。
- P2P分布式网络体系结构由众多的参与者结点,或者称之为对等结点组成,每个结点都可以为其他参与者提供一些服务,例如处理能力、硬盘存储、网络带宽等,
- 各个参与者之间直接交互,而不需要中间网络服务器。每个结点都是资源的提供者,同时又是资源的消费者。
- 一个没有中心服务器的P2P体系结构图如图所示。
无中心的P2P系统叫做纯P2P体系结构。
在纯P2P软件体系结构中,每个结点都是客户端,同时每个结点也都是服务器。
当一个结点作为客户端时,该结点有发送服务请求命令与接收服务结果的功能;而当该结点作为服务器时,该结点有接收服务请求命令、处理服务请求与执行该服务、发送响应与服务结果的功能。
P2P体系结构是一种分布式应用体系结构,这种体系结构能够将任务或负载分配到P2P网络中的各个对等结点上,而且无需服务器的集中协调,这些完全处于平等关系的对等结点就能够自行将自身的一些资源,如计算能力、磁盘存储或者网络带宽等,分拨出来供其他对等结点使用。
2.1 集中目录式P2P–第一代P2P软件体系结构
集中目录式P2P软件体系结构采用中央目录服务器管理P2P各结点,P2P结点向中央目录服务器注册关于名称、地址、资源、元数据、所能提供的服务等自身的信息,但所有内容存储在各结点中而非服务器上。
当一个结点要查找某种服务的时候,该结点首先要连接到目录服务器,然后根据目录服务器中的信息查询以及网络流量和延迟等信息来选择与定位其他对等点。一旦找到了所要连接的结点,则直接与其建立连接,而不必经过中央目录服务器进行。
目录服务器形式上是该对等网络的“中心”。但是,实际上目录服务器除了提供各结点的基本的已注册信息之外,并不真正地承担任何其他的功能,因此,该体系结构与传统的客户端 – 服务器体系结构还是有本质的区别。
集中目录式软件体系结构的结构图如图所示。
2.2 纯P2P-第二代P2P软件体系结构
纯P2P体系结构也被称为广播式的P2P模型,它没有集中的中央目录服务器,每个用户随机接入网络,并与自己相邻的一组邻居结点通过端到端连接构成一个逻辑覆盖的网络。每个对等结点都可以既作为客户端又作为服务器,且与它们的邻居都拥有相同的能力。每个对等结点都作为网络中的一个结点,没有中心路由器。原始的纯P2P体系结构图如图所示。
对等结点之间的内容查询和内容共享都是直接通过相邻结点广播接力传递,同时每个结点还可以记录搜索轨迹,以防止搜索环路的产生。纯P2P网络结构解决了网络结构中心化的问题,扩展性和容错性较好。
纯P2P体系结构具有如下缺点:
- 服务发现限制与困难。在大型P2P网络中,查询会遇到查询范围小的困难。
- 由于没有一个对等结点知道整个网络的结构,网络中的搜索算法以泛洪的方式进行,控制信息的泛滥消耗了大量带宽并且可能很快造成网络拥塞甚至网络的不稳定,从而导致整个网络的可用性较差。
- 系统容易受到垃圾信息,甚至是病毒的恶意攻击。
2.3 非结构化的层次纯P2P-第三代P2P软件体系结构
传统的纯P2P体系结构在运行中存在很多问题,主要体现在基于泛洪的第二代P2P网络中当网络变得很大时,系统的搜索/回答率会变得很低。
为了解决该问题,代表基于层次的第三代P2P系统在2001年应运而生。通过将对等结点分为超级结点与叶子结点两大类的方法,让超级结点形成一个建立在原来的对等网络之上的覆盖网络的方式,引入了层次的概念。
这种改良体系结构为非结构化的层次纯P2P体系结构,其网络拓扑结构如图所示。
- 叶子结点仅仅同它们的超级结点维持连接;而超级结点除了与自己的叶子结点维持连接以外,还连接到超级结点覆盖网中的其他的超级结点。
- 超级结点充当自己的叶子结点的代理结点。
- 超级结点负责将查询请求传递到其他的超级结点,或者,如果它准确地知道自己的某个叶结点能回答该请求,它会将该请求传递给该叶子结点。
2.4 练习
- 请简述P2P体系结构的概念。
答:P2P分布式网络体系结构由众多的参与者结点,或者称之为对等结点组成,每个结点都可以为其他参与者提供一些服务,各个参与者之间直接交互,而不需要中间网络服务器。每个结点都是资源的提供者,同时又都是资源的消费者。
- 第一代到第三代P2P体系结构分别叫什么?
答:集中目录式P2P体系结构,纯P2P体系结构,非结构化的层次纯P2P体系结构
- 请简述集中目录式P2P的优缺点。
答:集中目录式P2P体系结构的优点为,提高了网络的可管理性,使得对共享资源的查找和更新非常方便。其缺点为网络的稳定性比较差。一旦服务器失效,则该服务器下的对等结点可能全部失效。很明显,中心控制存在单点失效与不可扩展问题,同时中心目录服务器还很可能形成瓶颈问题。
3. 网格计算软件体系结构
- 网格计算是伴随着互联网技术而迅速发展起来的,针对复杂科学计算的新型计算模式。
- 这种计算模式是利用互联网把分散在不同地理位置的计算机以及其他设备组织成一个“虚拟的超级计算机”,其中每一台参与计算的计算机称为一个“计算结点”,或者简称为结点。
- 整个计算是由成千上万个“结点”组成的“一张网格”来完成的。这样组织起来的“虚拟的超级计算机”有两个优势,一个是数据处理能力超强,另一个是能充分利用网上的闲置处理能力。
- 简单地讲,网格是把整个网络整合成一台巨大的超级计算机,实现计算资源、存储资源、数据资源、信息资源、知识资源和专家资源的全面共享。
目前最常使用的网格主要有以下三种:
- 计算网格:计算网格是各个结点都有计算与处理能力的网格。这是最为常见的网格类型,它已被成功地用于执行一些计算密集型的任务。
- 数据网格:数据存储是数据网格的主要共享资源。这样的网格可被认为是集成了大量的存储设备而形成的巨大的数据存储系统。
- 网络网格:网络网格的主要目的是提供容错和高性能的通信服务。在这种网格中,每个网格结点在两个通信结点之间像数据路由器一样工作,提供数据缓存和其他的设施,以加速数据在通信结点的传输。
网格计算与P2P计算的比较:
- 网格计算强调资源整合、性能、服务质量和安全性等问题。
- P2P计算关注网络服务质量和支持问题。
3.1 练习
- 中国地震预测组织联盟包括几百家地震预报站,每个地震预报站都有高质量的可靠的实验设备,但是每个地震站又无能力对全国地区进行地震预报计算。国家地震局决定综合利用每个站的可靠的计算资源,包括各种传感器数据,以便达到实时性的地震预报。计算包含地址结构变化监测、断裂带监测、地下水位计算等。如果要进行综合实时预报软件的设计,并且要从下列体系结构中进行选择:
(1)网格计算体系结构;
(2)P2P软件体系结构。
那么选择哪种体系结构比较合适?请说明选择这种体系结构的原因。
解:
网格计算体系结构,网格计算体系结构偏向整合所有资源完成一件事,对性能,服务质量,安全性要求较高,P2P软件体系结构偏向资源的共享,题目中“国家地震局决定综合利用每个站的可靠的计算资源,包括各种传感器数据,以便达到实时性的地震预报”,比较适合网格计算体系结构。
- P2P软件体系结构与网格软件体系结构的主要区别是什么?如果要设计一个应用程序,为电影爱好者成立一个虚拟组织,使得电影爱好者可以通过互联网交换影片,那么:
(1)应从以上的两种体系结构中选择哪种?
(2)说明选择这个体系结构的原因是什么?
解:
网格计算强调资源整合、性能、服务质量和安全性等问题,P2P计算关注网络服务质量和支持问题。
(1)P2P软件体系结构
(2)网格计算体系结构偏向整合所有资源完成一件事,对性能,服务质量,安全性要求较高,P2P软件体系结构偏向资源的共享,电影爱好者可以通过互联网交换影片,即为电影资源的共享,比较适合P2P软件体系结构。
4. SOA软件体系结构
- SOA是一种面向服务的软件体系结构,服务是代表某一计算实体将被其他计算实体执行的工作单位。
- SOA定义了两个计算实体之间的交互,是利用网络上已有的服务创建新的软件应用的软件体系结构。该结构提倡软件组件之间松散耦合,以便实现组件的复用。SOA支持对企业遗留系统的复用,通过从各种异构的遗留系统中创建新的统一的服务,实现各系统之间的互操作性。
- SOA的一个重要特征是服务接口及其实现的分离。除此之外,服务还具有自包含的、松散的耦合,可被动态发现、可与其他服务聚合形成复合服务等特征。
SOA体系结构包含的组件为服务提供者、服务消费者和服务注册器,如图所示。
SOA工作机制如下:
- 服务提供者将要暴露的服务注册到公共服务注册器(Registry)中;
- 服务消费者查询服务注册器,寻找符合需求的服务。如果服务注册器中有这样的服务,它将为消费者提供该服务的描述信息;
- 服务消费者与服务提供者将直接绑定,服务提供者开始为服务消费者执行相应服务。
4.1 Web Service
SOA可以有不同的实现,而Web Service 就是该体系结构的一种实现。
Web Service通过HTTP协议传递XML格式的交互信息。通过这种技术中立的方式,提供了一种在异构应用之间进行交互操作的标准方案。由于Web Service实现了SOA体系结构,所以Web Service具有如图所描述的体系结构及服务发现、绑定与执行的工作机制。
在图中:
- XML是一种标准的。基于文字的、跨平台的可扩展标记语言。
- SOAP是基于HTTP协议之上实现服务消费者与提供者之间的交互协议。
- WSDL是基于XML的规范化的服务描述语言。
- UDDI是发布与寻找Web Service信息的技术规范。
4.2 练习
- Web Service与SOA体系结构的关系是什么? Web Service有什么好处?
解:
SOA可以有不同的实现,而Web Service 就是该体系结构的一种实现。
Web Services提供了一种能够在异构应用之间进行互操作的标准方案。Web Services可以被松散地组装在一起,以便实现更为复杂的业务操作。即便是原有提供简单服务的程序也可以通过互动而实现服务增值。
- 简述SOA体系结构的优势。
解:
和正常的 B2B电子商务不同的是,在SOA体系结构中,服务提供者与消费者之间不是静态绑定的,而是可以被自动发现和动态绑定的。SOA支持对企业遗留系统的复用,通过从各种异构的遗留系统中创建新的统一的服务,实现各系统之间的互操作性。
5. 云计算软件体系结构
定义
云计算是一种能够通过网络以便利的、按需付费的方式获取计算资源(包括网络、服务器、存储、应用和服务等)的范型,这些资源来自一个共享的、可配置的资源池,并能够以最省力和无人干预的方式获取和释放。
基本特点
- 按需自助服务:用户可以随时获得包括计算、存储、带宽等在内的计算资源,而不需要云服务提供者的人工参与。
- 不受限的网络访问:云服务可以通过各类型的远程访问机制和客户端来获取(例如,移动电话、笔记本电脑或掌上电脑等)。
- 资源池:服务提供者将计算资源汇集到资源池中,通过多租户模式共享给多个消费者,根据消费者的需求对不同的物理资源和虚拟资源进行动态分配或重分配。。
- 快速灵活:云服务可以快速提供、扩展和释放。对于用户来说,云服务是取之不尽的,并且在任意时间均可以使用。
- 可计量的服务:云系统通过不同层次的计量功能自动化地管理和优化资源使用。云服务的使用情况会被监测、控制和汇报,而这一过程对用户和提供者来说都是透明的。
服务模型
- 基础设施即服务(IaaS):该模式的云服务,提供处理器、存储、网络和其他基本计算资源的租用服务,允许消费者在其上部署、运行任意软件。
- 平台即服务(PaaS):该模式的云服务,提供指定类型应用的托管服务,消费者可以把用指定语言编写的程序创建和部署在云上。
- 软件即服务(SaaS):该模式的云服务,提供在云基础设施上运行的、由提供者创建的应用服务。这些应用可以被不同客户端设备访问、配置和使用,而应用的用户则不直接管理或控制包括网络、服务器、操作系统和存储等在内的底层云基础设施。
5.1 练习
- 云计算都提供哪些类型的服务?
解:
基础设施即服务、平台即服务、软件即服务
- 有哪些开源云计算软件产品,分别有何作用?
解:
Hadoop,Hadoop已被广泛用于一些商业云计算平台中,例如Amazon , Yahoo等公司都采用了Hadoop 。
案例分析
1. 主程序-子程序软件体系结构案例
试用主程序-子程序软件体系结构设计一个员工信息查询系统(Staff Information Query System),要求输入员工工号(Staff Number),输出该员工的信息(Staff Information),包括姓名(Name),部门(Department),月薪(Salary),联系电话(Phone)等。
请按要求画出数据流图和程序结构图。
解:
2. 管道-过滤器体系结构案例
使用管道-过滤器体系结构设计模拟C程序代码source.cpp的执行过程:
- 编译(Compiler):将source.cpp翻译成目标代码(compile()),目标代码是在目标机器上运行的代码。
- 链接(Linker): 将目标代码与C函数库相连接(link()),并将源程序所用的库代码与目标代码合并,并形成最终可执行的二进制机器代码。
- 执行(Execution): 在特定的机器环境下运行(execute())C程序。
要求画出设计类图,包括所有的类的设计与方法。
解:
3. 观察者模式案例
使用观察者模式设计一个类图来模拟日常快递的领取。
在该场景中,快递公司(Express)作为被观察者,实现了被观察者(Observable)接口的方法,能够注册观察者(addObserver)、改变状态信息(setChanged)并通知观察者快递信息(notifyObservers);教师(Teacher)和学生(Student)都是观察者,实现了观察者(Observer)接口的方法,当收到通知信息时采取相应操作(update)。
请按要求画出类图及其关键属性和操作。
解:
4. MVC软件体系结构案例
采用MVC体系结构(使用观察者机制)设计一个汽车销售系统。
在该场景中,汽车(CarModel)作为被观察者,实现了被观察者(Observable)接口的方法,能够通知观察者汽车的信息(notifyObservers)、注册观察者(register),并使用列表(observersList)来保存观察者;界面由用户图形输入界面(CarAuctionGUI)、汽车介绍界面(CarGUIView)、剩余数量界面(CarBitView)组成,其中CarGUIView和CarBitView都是观察者,实现了观察者(Observer)接口的方法,当收到信息时采取相应操作(update);控制器类(Controller)处理用户输入,使用actionPerformance()方法对用户输入做出响应。
要求用户输入界面和显示视图独立显示。请按要求画出类图及其关键属性和操作。
解: