软考|系分|第十二章|软件架构设计(上)传统的软件开发过程可以划分为从概念到实现的若干个阶段,包括软件计划、需求分析、 软件设计、软件实现和软件测试等。在这种开发过程中,如何将需求分析的成果转换为软件设 计,这个问题一直困扰着研究人员和实践工作者。近年来,软件工程界提出了各种需求工程和 软件建模技术,然而,在软件需求和设计之间仍然存在一条很难逾越的鸿沟,从而很难有效地 将需求转换为相应的设计。为此,学者们提出了软件架构( Software Architecture) 的概念,并 试图在软件需求与设计之间架起一座桥梁,重点解决系统结构和需求向实现平坦过渡的问题。另一方面,随着软件系统规模越来越大、越来越复杂,整个系统的结构和规格说明显得越 来越重要。在这种背景下,人们也逐渐认识到软件架构的重要性,促进了软件架构技术的快速 发展和应用。 软件架构为软件系统提供了一个结构、行为和属性的高级抽象,由构件的描述、构件的相互 作用(连接件)、指导构件集成的模式以及这些模式的约束组成。软件架构指定了系统的组织结 构和拓扑结构,并且显示了系统需求和构件之间的对应关系,提供了一些设计决策的基本原理。软件架构虽脱胎于软件工程,但其形成也借鉴了计算机架构和网络架构中很多宝贵的思想 和方法。近年来,软件架构已完全独立于软件工程,成为计算机科学的一个最新的研究方向和 独立学科分支。软件架构研究的主要内容涉及软件架构描述、软件架构风格、软件架构评估和 软件架构的形式化方法等。解决好软件的复用、质量和维护问题,是研究软件架构的根本目的。对于软件项目的开发来说,一个清晰的软件架构是首要的。鉴于架构的重要性,Perry 将 软件架构视为软件开发中第一类重要的设计对象,Barry Boehm 也明确指出:“在没有设计出架 构及其规则时,那么整个项目不能继续下去,而且架构应该看作是软件开发中可交付的中间产 品”。由此可见,架构在软件开发中为不同的人员提供了共同的交流语言,体现并尝试了系统早 期的设计决策,并作为系统设计的抽象,为实现框架和构件的共享和重用、基于架构的软件开 发提供了有力的支持。(1)架构是项目干系人进行交流的手段。软件架构代表了系统的高层抽象,不同的项目干 系人关心着系统的不同方面,而这些方面都受架构的影响,因此,架构可能是所有项目干系人 共同关心的一个重要因素。例如,用户关心系统是否满足可用性和可靠性需求;客户关心的是 系统能否在规定时间内完成,并且开支在预算范围内;管理人员担心在经费支出和进度条件下, 按此架构能否使开发团队成员在一定程度上独立开发,各部分的交互是否遵循统一的规范,开 发进度是否可控;开发人员关心的是如何才能实现架构的各项目标。(2)架构是早期设计决策的体现。软件架构体现了系统最早的一组设计决策,这些早期的 约束比起以后的开发、设计、编码或运行及维护阶段的工作重要得多,对系统生命周期的影 响也大得多。早期决策的正确性最难以保证,而且这些决策也最难以改变,影响范围也最大。(3)架构明确了对系统实现的约束条件。所谓“实现”就是要用实体来显示出一个软件架 构,即要符合架构所描述的结构性设计决策,分割成规定的构件,按规定方式互相交互。在具 体实现时,必须按照架构的设计,将系统分成若干个组成部分,各部分必须按照预定的方式进 行交互,而且每个部分也必须具有架构中所规定的外部特征。这些约束是在系统级或项目范围 内作出的,每个构件上工作的实现者是看不见的。这样一来,可以分离关注点,架构设计师不 必是算法设计者或精通编程语言,他们只需重点考虑系统的总体权衡( tradeoff) 问题,而构件 的开发人员在架构给定的约束下进行开发。(4)架构决定了开发和维护组织的组织结构。架构包含了对系统的最高层次的分解,因此 一般被作为任务划分结构的基础。任务划分结构又规定了计划、调度及预算的单位,决定了开 发小组内部交流的渠道、配置控制和文件系统的组织、集成与测试计划和过程等。各开发小组 按照架构中对各主要构件接口的规定进行交流。一旦进入维护阶段,维护活动也会反映出软件 架构,常由不同的小组分别负责对各具体部分的维护。(5)架构制约着系统的质量属性。小的软件系统可以通过编程或调试措施来达到质量属性 的要求,而随着软件系统规模的扩大,这种技巧也将越来越无法满足要求。因为在大型软件系 统中,质量属性更多的是由系统结构和功能划分来实现的,而不再主要依靠所选用的算法或数 据结构。可以使用对架构的评价来预测系统未来的质量属性,架构评估技术可以对按某架构开 发出来的软件产品的质量及缺陷做出比较准确的预测。(6)架构使推理和控制更改更简单。在整个软件生命周期内,每个架构都将更改划分为三 类,分别是局部的、非局部的和架构级的变更。局部变更是最经常发生的,也是最容易进行的, 只需修改某一个构件就可以实现。非局部变更的实现则需对多个构件进行修改,但并不改动软 件架构。架构级的变更是指会影响各部分的相互关系,甚至要改动整个系统。所以,一个优秀 的架构应该能使更改简单易行。(7)架构有助于循序渐进的原型设计。一旦确定了架构,就可以对它进行分析,并将它按 可执行模型来构造原型,以减少项目开发中的潜在风险。(8)架构可以作为培训的基础。在对项目组新成员介绍所开发的系统时,可以首先介绍系 统的架构,以及对构件之间如何交互从而实现系统需求的高层次的描述,让项目新成员能很快 进入角色。(9)架构是可传递和可复用的模型。软件架构体现了一个相对来说比较小又可理解的模型。 软件架构级的复用意味着架构的决策能在具有相似需求的多个系统中发生影响,这比代码级的 复用要有更大的好处。通过对架构的抽象,架构设计师能够对一些经过实践证明是非常有效的 架构进行复用,从而提高设计的效率和可靠性。在软件系统规模迅速增大的同时,软件开发方法也经历了一系列的变革。在此过程中,软件架构也由最初模糊的概念发展到一个渐趋成熟的理论和技术。20世纪70年代以前,尤其是在以ALGOL68 为代表的高级语言出现以前,软件开发基本 上都是汇编程序设计,此阶段系统规模较小,很少明确考虑系统结构,一般不存在系统建模工 作。20世纪70年代中后期,由于结构化开发方法的出现与广泛应用,软件开发中出现了概要 设计与详细设计,其主要任务是数据流设计与控制流设计,此时软件结构已作为一个明确的概 念出现在系统开发中。20世纪80年代初到90年代中期,是00方法兴起与成熟阶段。由于对象是数据与基于数 据之上操作的封装。因此,在00方法下,数据流设计与控制流设计统一为对象建模,同时, 00方法还提出了一些其他的结构视图。例如,OMT 方法提出了功能视图、对象视图和动态视 图 ,Booch方法提出了类图、对象图、状态迁移图、交互图、模块图和进程图,UML 则从功能 模型、静态模型、动态模型和配置模型等方面描述应用系统的结构。20世纪90年代以后,是基于构件的软件开发阶段。该阶段以过程为中心,强调软件开发 采用构件化技术和架构技术,要求开发出的软件具备很强的自适应性、互操作性、可扩展性和 可复用性。此阶段中,软件架构已经作为一个明确的文档和中间产品存在于软件开发过程中。 同时,软件架构作为一门学科逐渐得到人们的重视,并成为软件工程领域的研究热点。纵观软件架构技术的发展过程,从最初的无架构设计到现行的基于架构的软件开发,经历 了4个阶段:(1)无架构设计阶段。以汇编语言进行小规模应用程序开发为特征。(2)萌芽阶段。出现了程序结构设计主题,以控制流图和数据流图构成软件结构为特征。(3)初级阶段。出现了从不同侧面描述系统的结构模型,以UML 为典型代表。(4) 高级阶段。以描述系统的高层抽象结构为中心,不关心具体的建模细节,划分了架构 模型与传统软件结构的界限。该阶段以Kruchten提出的“4+1”模型为标志。有关该模型的详 细知识将在12.2节中介绍。 软件架构设计的首要问题是如何表示软件架构,即如何对软件架构建模。根据建模的侧重 点不同,可以把软件架构的模型分为5种,分别是结构模型、框架模型、动态模型、过程模型 和功能模型。(1)结构模型。这是一种最直观和最普遍的建模方法,它以构件、连接件和其他概念来刻 画架构,并力图通过架构来反映系统的重要语义内容,包括系统的配置、约束、隐含的假设条 件、风格和性质等。研究结构模型的核心是架构描述语言。(2)框架模型。框架模型与结构模型类似,但它不太侧重描述结构的细节而更侧重于整体 结构。框架模型主要以一些特殊的问题为目标建立只针对和适应该问题的架构。(3)动态模型。动态模型是对结构模型或框架模型的补充,研究系统的粗粒度行为性质。 例如,描述系统的重新配置或演化等,这类系统通常是激励型的。(4)过程模型。过程模型研究构建系统的步骤和过程。(5)功能模型。功能模型认为架构是由一组功能构件按层次组成的,下层向上层提供服务。 功能模型可以看作是一种特殊的框架模型。在上述5种模型中,最常用的是结构模型和动态模型。这5种模型各有所长,将它们有机地 统一在一起,形成一个完整的模型来刻画软件架构更合适。例如,Kruchten在1995年提出了一个 “4+1”的视图模型。“4+1”视图模型从5个不同的视角来描述软件架构,每个视图只关心系统的 一个侧面,5个视图结合在一起才能反映软件架构的全部内容。“4+1”视图模型如图12-1所示。 (1) 逻辑视图。逻辑视图主要支持系统的功能需求,即系统提供给最终用户的服务。在逻 辑视图中,系统分解成一系列的功能抽象,这些抽象主要来自问题领域。这种分解不但可以用 来进行功能分析,而且可用作标识在整个系统的各个不同部分的通用机制和设计元素。在00 技术中,通过抽象、封装和继承,可以用对象模型来代表逻辑视图,用类图来描述逻辑视图。 逻辑视图中使用的风格为面向对象的风格,在设计中要注意保持一个单一的、内聚的对象模型 贯穿整个系统。(2)开发视图。开发视图也称为模块视图,在UML中被称为实现视图,它主要侧重于软 件模块的组织和管理。开发视图要考虑软件内部的需求,例如,软件开发的容易性、软件复用 和软件的通用性,要充分考虑由于具体开发工具的不同而带来的局限性。开发视图通过系统I/O 关系的模型图和子系统图来描述。(3)进程视图。进程视图侧重于系统的运行特性,主要关注一些非功能性需求,例如,系 统的性能和可用性等。进程视图强调并发性、分布性、系统集成性和容错能力,以及逻辑视图 中的功能抽象如何适合进程结构等,它也定义了逻辑视图中的各个类的操作具体是在哪一个线 程中被执行的。进程视图可以描述成多层抽象,每个级别分别关注不同的方面。(4)物理视图。物理视图在UML中被称为部署视图,主要考虑如何把软件映射到硬件上,它通常要考虑到解决系统拓扑结构、系统安装和通信等问题。当软件运行于不同的物理节点上 时,各视图中的构件都直接或间接地对应于系统的不同节点上。因此,从软件到节点的映射要 有较高的灵活性,当环境改变时,对系统其他视图的影响最小化。(5)场景。场景可以看作是那些重要系统活动的抽象,它使4个视图有机联系起来,从某 种意义上说场景是最重要的需求抽象。场景视图对应UML中的用例视图。在开发软件架构时, 它可以帮助架构设计师找到构件及其相互关系。同时,架构设计师也可以用场景来分析一个特定的视图,或描述不同视图的构件之间是如何相互作用的。场景可以用文本表示,也可以用图 形表示。例如,图12-2是一个小型电话呼叫系统场景片段的图形描述,相应的文本表示如下:①小王的电话控制器检测和验证电话从挂机到摘机状态的转变,且发送一个消息以唤醒相 应的终端对象。②终端分配一定的资源,且通知控制器发出某种拨号音。 从以上分析可知,逻辑视图和开发视图描述系统的静态结构,而进程视图和物理视图描述 系统的动态结构。对于不同的软件系统来说,侧重角度也有所不同。例如,对于MIS 来说,比 较侧重于从逻辑视图和开发视图来描述系统;而对于实时控制系统来说,则比较注重于从进程 视图和物理视图来描述系统。 软件架构,即软件体系结构。软件体系结构设计的一个核心目标是重复的体系结构模式, 即达到体系结构级的软件重用。也就是说,在不同的软件系统中,使用同一体系结构。基于这 个目标,主要任务是研究和实践软件体系结构风格和类型问题。 软件体系结构风格是描述某一特定应用领域中系统组织方式的惯用模式。体系结构风格定 义一个系统家族,即一个体系结构定义一个词汇表和一组约束。词汇表中包含一些构件和连接 件类型,而这组约束指出系统是如何将这些构件和连接件组合起来的。体系结构风格反映了领 域中众多系统所共有的结构和语义特性,并指导如何将各个模块和子系统有效地组织成一个完 整的系统。对软件体系结构风格的研究和实践促进对设计的重用,一些经过实践证实的解决方 案也可以可靠地用于解决新的问题。例如,如果某人把系统描述为“客户/服务器”模式,则 不必给出设计细节,我们立刻就会明白系统是如何组织和工作的。 数据流体系结构是一种计算机体系结构,直接与传统的冯 ·诺依曼体系结构或控制流体系 结构进行了对比。数据流体系结构没有概念上的程序计数器:指令的可执行性和执行仅基于指 令输入参数的可用性来确定,因此,指令执行的顺序是不可预测的,即行为是不确定的。数据 流体系结构风格主要包括批处理风格和管道-过滤器风格。 在批处理风格(如图12-3所示)的软件体系结构中,每个处理步骤是一个单独的程序,每一 步必须在前一步结束后才能开始,并且数据必须是完整的,以整体的方式传递。它的基本构件是 独立的应用程序,连接件是某种类型的媒介。连接件定义了相应的数据流图,表达拓扑结构。当数据源源不断地产生,系统就需要对这些数据进行若干处理(分析、计算、转换等)。现 有的解决方案是把系统分解为几个序贯的处理步骤,这些步骤之间通过数据流连接,一个步骤 的输出是另一个步骤的输入。每个处理步骤由一个过滤器( Filter) 实现,处理步骤之间的数据 传输由管道( Pipe) 负责。每个处理步骤(过滤器)都有一组输入和输出,过滤器从管道中读 取输入的数据流,经过内部处理,然后产生输出数据流并写入管道中。因此,管道-过滤器体 系结构风格(如图12-4所示)的基本构件是过滤器,连接件是数据流传输管道,将一个过滤器 的输出传到另一过滤器的输入。调用返回体系结构风格是指在系统中采用了调用与返回机制。利用调用-返回实际上是一种分而治之的策略,其主要思想是将一个复杂的大系统分解为若干子系统,以便降低复杂度, 并且增加可修改性。程序从其执行起点开始执行该构件的代码,程序执行结束,将控制返回给 程序调用构件。调用/返回体系结构风格主要包括主程序/子程序风格、面向对象风格、层次型 风格以及客户端/服务器风格。 主程序/子程序风格一般采用单线程控制,把问题划分为若干处理步骤,构件即为主程序 和子程序。子程序通常可合成为模块。过程调用作为交互机制,即充当连接件。调用关系具有 层次性,其语义逻辑表现为子程序的正确性取决于它调用的子程序的正确性。抽象数据类型概念对软件系统有着重要作 用,目前软件界已普遍转向使用面向对象系统。 这种风格建立在数据抽象和面向对象的基础上, 数据的表示方法和它们的相应操作封装在一个 抽象数据类型或对象中。这种风格的构件是对 象,或者说是抽象数据类型的实例(如图12-5 所示)。层次系统(如图12-6所示)的组成为一个层 次结构,每一层为上层提供服务,并作为下层的 客户。在一些层次系统中,除了一些精心挑选的 输出函数外,内部的层接口只对相邻的层可见。 在这样的系统中,构件在层上实现了虚拟机。连 接件由决定层间如何交互的协议来定义,拓扑约 束包括对相邻层间交互的约束。由于每一层最多 只影响两层,同时只要给相邻层提供相同的接 口,允许每层用不同的方法实现,这同样为软件 重用提供了强大的支持。在IT 发展过程中,网络计算经历了从集中式计算模型到分布式计算模型的演变。在集中式 计算技术时代,广泛使用的是大型机(或小型机)计算模型。它是通过一台物理上与宿主机相 连接的非智能终端来实现宿主机上的应用程序。在多用户环境中,宿主机应用程序既负责与用 户的交互,又负责对数据的管理。集中式的系统使用户能共享贵重的硬件设备,例如,磁盘机、打印机和调制解调器等。但随着用户的增多,对宿主机能力的要求增高,而且开发人员必须为 每个新的应用重新设计同样的数据管理构件。20世纪80年代以后,集中式结构逐渐被以PC 为主的微机网络所取代。PC 和工作站的采用,永远改变了协作计算模型,导致了分布式计算模型的产生。一方面,由于大型机系统固有 的缺陷(例如,缺乏灵活性),无法适应信息量急剧增长的需求,并为整个企业提供全面的解决 方案;另一方面,由于微处理器的日新月异,其强大的处理能力和低廉的价格使微机网络迅速 发展,用户可以选择适合自己需要的工作站、操作系统和应用程序。客户机/服务器(Client/Server,C/S) 架构是基于资源不对等,且为实现共享而提出来的, 是20世纪90年代成熟起来的技术,C/S 架构定义了工作站(客户应用程序)如何与服务器相 连,以实现数据和应用分布到多台计算机上。服务器负责有效地管理系统的资源,其主要任务 集中于对DBMS的管理和控制,以及数据的备份与恢复;客户应用程序的主要任务是提供用户 与数据库交互的界面,向服务器提交用户请求并接收来自服务器的信息,对存在于客户端的数 据执行应用逻辑要求。这是一种“胖客户机( fat client)、瘦服务器(thin server)” 的架构,其 处理流程如图12-7所示。 与集中式系统相比,C/S 架构的优点主要在于,系统的客户应用程序和服务器构件分别运 行在不同的计算机上,系统中每台服务器都可以适合各构件的要求,这对于硬件和软件的变化 显示出极大的适应性和灵活性,而且易于对系统进行扩充和缩小。在C/S 架构中,系统中的功 能构件充分隔离,客户应用程序的开发集中于数据的显示和分析,而服务器的开发则集中于数 据的管理,不必在每一个新的应用程序中都要对一个DBMS进行编码。将大的应用处理任务分 布到许多通过网络连接的低成本计算机上,以节约大量费用。C/S架构具有强大的数据操作和事务处理能力,模型思想简单,易被人们理解和接受。但 随着企业规模的日益扩大,软件的复杂程度不断提高,C/S 架构逐渐暴露出以下缺点:(1)开发成本较高。C/S 架构对客户端软硬件配置要求较高,尤其是软件的不断升级,对 硬件要求不断提高,增加了整个系统的成本。(2)客户端程序设计复杂。采用C/S 架构进行软件开发,大部分工作量放在客户端的程序 设计上,客户端显得十分庞大。(3)用户界面风格不一,使用繁杂,不利于推广使用。(4)软件移植困难。采用不同开发工具或平台开发的软件,一般互不兼容,不能或很难移 植到其他平台上运行。(5)软件维护和升级困难。采用C/S 架构的软件要升级,开发人员必须到现场为客户机升 级,每个客户机上的软件都需要维护。对软件的一个小小改动,每一个客户端都必须更新。(6)新技术不能轻易应用。因为一个软件平台及开发工具一旦选定,不可能轻易更改。(7)可扩展性差。C/S 架构是单一服务器且以局域网为中心的,所以难以扩展至大型企业 广域网或Internet, 软硬件的组合和集成能力有限。客户机的负荷太重,难以管理大量的客户 机,系统的性能容易变坏。(8)系统安全性难以保证。因为客户端程序可以直接访问数据库服务器,所以,在客户端 计算机上的其他程序也可想办法访问数据库服务器,从而使数据库的安全性受到威胁。正是因为C/S 架构有这么多缺点,因此,三层C/S架构应运而生。为了区分,把传统的C/S 架构称为二层C/S 架构。与二层C/S 架构相比,在三层C/S 架构中,增加了一个应用服务器。可以将整个应用逻辑 驻留在应用服务器上,而只有表示层存在于客户机上。这种客户机称为瘦客户机( thin client)。 三层C/S 架构将应用系统分成表示层、功能层和数据层三个部分,如图12-8所示。(1)表示层。表示层是系统的用户接口部分,担负着用户与系统之间的对话功能。它用于检 查用户从键盘等输入的数据,显示输出的数据。为使用户能直观地进行操作,通常使用图形用户 界面,操作简单、易学易用。在变更用户界面时,只需改写显示控制和数据检查程序,而不影 响其他两层。检查的内容也只限于数据的形式和取值的范围,不包括有关业务本身的处理逻辑。(2)功能层。功能层也称为业务逻辑层,是将具体的业务处理逻辑编入程序中。例如,在 制作订购合同时要计算合同金额、按照预定的格式配置数据、打印订购合同,而处理所需的数 据则要从表示层或数据层取得。(3)数据层。数据层相当于二层C/S 架构中的服务器,负责对DBMS进行管理和控制。三层C/S 架构对这三层进行明确分割,并在逻辑上使其独立。在二层C/S 架构中,数据层 作为DBMS 已经独立出来,所以,三层C/S 架构的关键是要将表示层和功能层分离成各自独立 的程序,并且还要使这两层间的接口简洁明了。通常的做法是只将表示层配置在客户机中,如 图12-9( a) 或图12-9( b) 所示。如果像图12-9( c) 所示的那样连功能层也放在客户机中,与 二层C/S 架构相比,其程序的可维护性要好得多,但是其他问题并未得到解决。客户机的负荷 太重,其业务处理所需的数据要从服务器传给客户机,所以系统的性能容易变坏。 (a) 将数据层和 (b) 将数据层和 (c) 将功能层 功能层放在同一 功能层放在不同 放在客户机上 如果将功能层和数据层分别放在不同的服务器中,如图12-9( b) 所示,则服务器之间也要 进行数据传送。由于三层是分别放在各自不同的硬件系统上的,所以灵活性很高,能够适应客 户机数目的增加和处理负荷的变动。例如,在追加新业务处理时,可以相应增加装载功能层的 服务器(应用服务器)。因此,系统规模越大,这种形态的优点就越显著。在三层C/S 架构中, 中间件是最重要的构件。与传统的二层C/S 架构相比,三层C/S 架构具有以下优点:(1)允许合理地划分三层的功能,使之在逻辑上保持相对独立性,从而使整个系统的逻辑 结构更为清晰,能提高系统的可维护性和可扩展性。(2)允许更灵活、有效地选用相应的平台和硬件系统,使之在处理负荷能力上与处理特性上 分别适应于结构清晰的三层,并且这些平台和各个组成部分可以具有良好的可升级性和开放性。(3)系统的各层可以并行开发,各层也可以选择各自最适合的开发语言,使之能并行且高效地进行开发,达到较高的性能价格比。对每一层的处理逻辑的开发和维护也会更容易些。(4)利用功能层可以有效地隔离表示层与数据层,未授权的用户难以绕过功能层而利用数 据库工具或黑客手段非法访问数据层,这就为严格的安全管理奠定了坚实的基础。但是,若三层C/S 架构各层间的通信效率不高,即使分配给各层的硬件能力很强,其作为 整体来说也达不到所要求的性能。此外,设计时必须慎重考虑三层间的通信方法、通信频度和 数据量,这是三层C/S 架构设计的关键问题。浏览器/服务器(Browser/Server,B/S) 架构是三层C/S 架构的一种实现方式,其具体结构 为“浏览器/Web服务器/数据库服务器”。B/S 架构利用不断成熟的WWW 浏览器技术,结合 浏览器的多种脚本语言,用通用浏览器就实现了原来需要复杂的专用软件才能实现的强大功能, 并节约了开发成本。从某种程度上来说,B/S 架构是一种全新的软件架构。在B/S 架构中,除了数据库服务器外,应用程序以网页形式存放于Web服务器上,用户 运行某个应用程序时,只需在客户端的浏览器中键入相应的网址,调用Web 服务器上的应用程 序,并对数据库进行操作,完成相应的数据处理工作,最后将结果通过浏览器显示给用户。基 于B/S架构的软件,系统安装、修改和维护全在服务器端解决。用户在使用系统时,仅仅需要 一个浏览器就可运行全部的模块,真正达到了“零客户端”的功能,很容易在运行时自动升级。但是,与C/S 架构相比,B/S 架构也有许多不足之处,例如,缺乏对动态页面的支持能力, 没有集成有效的数据库处理功能;安全性难以控制;采用B/S架构的系统在数据查询等响应速 度上远远低于C/S 架构;B/S 架构的数据提交一般以页面为单位,数据的动态交互性不强,不利 于OLTP应用。以数据为中心的体系结构风格主要包括仓库风格和黑板风格。仓库( repository) 是存储和维护数据的中心场所。在仓库体系结构风格(如图12-10所示) 中,有两种不同的构件:中央数据结构(说明当前数据的状态),以及一组对中央数据进行操作 的独立构件,仓库与独立构件间的相互作用在系统中会有大的变化。这种风格的连接件即为仓 库与独立构件之间的交互。黑板体系结构风格(如图12-11所示)适用于解决复杂的非结构化问题,能在求解过程中 综合运用多种不同的知识源,使得问题的表 达、组织和求解变得比较容易。黑板系统是 一种问题求解模型,是组织推理步骤、控制 状态数据和问题求解的领域知识的概念框架。 它将问题的解空间组织成一个或多个与应用 相关的分级结构。分级结构的每一层信息由 一个唯一的词汇来描述,它代表了问题的部 分解。领域相关的知识被分成独立的知识模 块,它将某一层次中的信息转换成同层或相 邻层的信息。各种应用通过不同知识表达方 法、推理框架和控制机制的组合来实现。影响黑板系统设计的最大因素是应用问题本身的特性。支撑应用程序的黑板体系结构有许 多相似的特征和构件。对于特定应用问题,黑板系统可通过选取各种黑板、知识源和控制模块 的构件来设计,也可以利用预先定制的黑板体系结构的编程环境。黑板系统的传统应用是信号 处理领域,如语音识别和模式识别。另一应用是松耦合代理数据共享存取。 虚拟机体系结构风格的基本思想是人为构建一个运行环境,在这个环境之上,可以解析与 运行自定义的一些语言,这样来增加架构的灵活性。虚拟机体系结构风格主要包括解释器风格 和规则系统风格。一个解释器通常包括完成解释工作的解释引擎,一个包含将被解释的代码的存储区,一个 记录解释引擎当前工作状态的数据结构,以及一个记录源代码被解释执行进度的数据结构。具有解释器风格(如图12-12所示)的软件中含有一个虚拟机,可以仿真硬件的执行过程 和一些关键应用。解释器通常被用来建立一种虚拟机以弥合程序语义与硬件语义之间的差异, 其缺点是执行效率较低。典型的例子是专家系统。基于规则的系统(如图12-13所示)包括规则集、规则解释器、规则/数据选择器及工作 内存。独立构件风格主要强调系统中的每个构件都是相对独立的个体,它们之间不直接通信,以 降低耦合度,提升灵活性。独立构件风格主要包括进程通信和事件系统风格。在进程通信结构体系结构风格中,构件是独立的过程,连接件是消息传递。这种风格的 特点是:构件通常是命名过程,消息传递的方式可以是点到点、异步或同步方式及远程过程调 用等。事件系统风格(如图12-14所示)基于事件的隐式调用风格的思想,构件不直接调用一个 过程,而是触发或广播一个或多个事件。系统中其他构件中的过程在一个或多个事件中注册, 当一个事件被触发,系统自动调用在这个事件中注册的所有过程,这样,一个事件的触发就导 致了另一模块中的过程的调用。从架构上说,这种风格的构件是一些模块,这些模块既可以是一些过程,又可以是一些事 件的集合。过程可以用通用的方式调用,也可以在系统事件中注册一些过程,当发生这些事件 时,过程被调用。基于事件的隐式调用风格的主要特点是事件的触发者并不知道哪些构件会被这些事件影响。 这使得不能假定构件的处理顺序,甚至不知道哪些过程会被调用,因此,许多隐式调用的系统 也包含显式调用作为构件交互的补充形式。支持基于事件的隐式调用的应用系统很多。例如,在编程环境中用于集成各种工具,在 数据库管理系统中确保数据的一致性约束,在用户界面系统中管理数据,以及在编辑器中支 持语法检查。例如在某系统中,编辑器和变量监视器可以登记相应 Debugger 的断点事件。当 Debugger在断点处停下时,它声明该事件,由系统自动调用处理程序,如编辑器可以卷屏(返 回)到断点,变量监视器刷新变量数值。而Debugger本身只声明事件,并不关心哪些过程会启 动,也不关心这些过程做什么处理。迄今为止,对于面向服务的架构( Service-Oriented Architecture,SOA) 还没有一个公认的 定义。许多组织从不同的角度和不同的侧面对SOA 进行了描述,较为典型的有以下三个:(1) W3C 的定义:SOA 是一种应用程序架构,在这种架构中,所有功能都定义为独立的 服务,这些服务带有定义明确的可调用接口,能够以定义好的顺序调用这些服务来形成业务 流程。(2)Service-architecture. com 的定义:服务是精确定义、封装完善、独立于其他服务 所处环境和状态的函数。SOA 本质上是服务的集合,服务之间彼此通信,这种通信可能是简 单的数据传送,也可能是两个或更多的服务协调进行某些活动。服务之间需要某些方法进行 连接。(3) Gartner 的定义:SOA 是一种C/S 架构的软件设计方法,应用由服务和服务使用者组成, SOA 与大多数通用的C/S 架构模型不同之处,在 于它着重强调构件的松散耦合,并使用独立的 标准接口。SOA 是一种在计算环境中设计、开发、部署和管理离散逻辑单元(服务)模型的方法。 SOA并不是一个新鲜事物,而只是面向对象模型的一种替代。虽然基于SOA 的系统并不排除 使 用 0OD来构建单个服务,但是其整体设计却是面向服务的。由于SOA 考虑到了系统内的对 象,所以虽然SOA 是基于对象的,但是作为一个整体,它却不是面向对象的。SOA 系统原型的一个典型例子是CORBA, 它已经出现很长时间,其定义的概念与SOA 相 似。SOA 建立在XML 等新技术的基础上,通过使用基于XML 的语言来描述接口,服务已经转 到更动态且更灵活的接口系统中,CORBA 中的IDL 无法与之相比。图12-15描述了一个完整的 SOA 模型。 在SOA 模型中,所有的功能都定义成了独立的服务。服务之间通过交互和协调完成业务的 整体逻辑。所有的服务通过服务总线或流程管理器来连接。这种松散耦合的架构使得各服务在 交互过程中无须考虑双方的内部实现细节,以及部署在什么平台上。 从图12-16可以看出,服务模型的表示层从逻辑层分离出来,中间增加了服务对外的接口 层。通过服务接口的标准化描述,使得服务可以提供给任何异构平台和任何用户接口使用。这 允许并支持基于服务的系统成为松散耦合、面向构件和跨技术实现的,服务请求者很可能根本 不知道服务在哪里运行、是由哪种语言编写,以及消息的传输路径,而是只需要提出服务请求, 然后就会得到答案。SOA架构继承了来自对象和构件设计的各种原则,例如,封装和自我包含等。那些保证服 务的灵活性、松散耦合和复用能力的设计原则,对 SO A架构来说同样是非常重要的。关于服 务,一些常见的设计原则如下:(1)明确定义的接口。服务请求者依赖于服务规约来调用服务,因此,服务定义必须长时 间稳定,一旦公布,不能随意更改;服务的定义应尽可能明确,减少请求者的不适当使用;不 要让请求者看到服务内部的私有数据。(2)自包含和模块化。服务封装了那些在业务上稳定、重复出现的活动和构件,实现服务 的功能实体是完全独立自主的,独立进行部署、版本控制、自我管理和恢复。(3)粗粒度。服务数量不应该太多,依靠消息交互而不是远程过程调用,通常消息量比较 大,但是服务之间的交互频度较低。(4)松耦合。服务请求者可见的是服务的接口,其位置、实现技术、当前状态和私有数据 等,对服务请求者而言是不可见的。(5)互操作性、兼容和策略声明。为了确保服务规约的全面和明确,策略成为一个越来越 重要的方面。这可以是与技术相关的内容,例如,一个服务对安全性方面的要求;也可以是与 业务有关的语义方面的内容,例如,需要满足的费用或者服务级别方面的要求,这些策略服务 的交互是非常重要的。服务构件架构 ( Service Component Architecture,SCA) 是基于SOA 思想描述服务之间组 合和协作的规范,它用于描述使用SOA 构建应用程序和系统的模型。它可简化使用SOA 进 行的应用程序开发和实现工作。SCA 提供了构建粗粒度构件的机制,这些粗粒度构件由细粒 度构件组装而成。SCA 将传统中间件编程从业务逻辑分离出来,从而使程序员免受其复杂性的 困扰。它允许开发人员集中精力编写业务逻辑,而不必将大量的时间花费在更为底层的技术实 现上。SCA 服务构件与传统构件的主要区别在于,服务构件往往是粗粒度的,而传统构件以细粒 度居多;服务构件的接口是标准的,主要是服务描述语言接口,而传统构件常以具体API 的形 式出现;服务构件的实现与语言是无关的,而传统构件常绑定某种特定的语言;服务构件可以 通过构件容器提供QoS 的服务,而传统构件完全由程序代码直接控制。SOA伴随着无处不在的标准,为企业的现有资产或投资带来了更好的复用性。SOA 能够在最新的和现有的系统之上创建应用,借助现有的应用产生新的服务,为企业提供更好的灵活性来构建系统和业务流程。SOA是一种全新的架构,为了支持其各种特性,相关的技术规范不断推出。与SOA紧密相关的技术主要有统一描述、发现和集成(Universal Description Discoveryand Integration,UDDI)、Web服务描述语言(WebService Description Language,WSDL)、简单对象访问协议(SimpleObjectAccessProtocol,SOAP)和表述性状态转移(RepresentationalState Transfer, REST)等,而这些技术都是以XML为基础发展起来的。UDDI 提供了一种服务发布、查找和定位的方法,是服务的信息注册规范,以便被需要该 服务的用户发现和使用它。UDDI规范描述了服务的概念,同时也定义了一种编程接口。通过 UDDI提供的标准接口,企业可以发布自己的服务供其他企业查询和调用,也可以查询特定服 务的描述信息,并动态绑定到该服务上。(1)数据模型。UDDI数据模型是一个用于描述业务组织和服务的XML Schema。(2) API。UDDIAPI是一组用于查找或发布UDDI数据的方法,UDDIAPI基于SOAP。(3)注册服务。UDDI注册服务是SOA 中的一种基础设施,对应着服务注册中心的角色。WSDL是对服务进行描述的语言,它有一套基于 XML的语法定义。WSDL 描述的重点是服务,它包含 服务实现定义和服务接口定义,如图12-17所示。采用抽象接口定义对于提高系统的扩展性很有帮 助。服务接口定义就是一种抽象的、可重用的定义, 行业标准组织可以使用这种抽象的定义来规定一些标 准的服务类型,服务实现者可以根据这些标准定义来 实现具体的服务。定的服务接口。服务实现定义中包含对服务和端口的描述。一个服务往往会包含多个服务访问 入口,而每个访问入口都会使用一个端口元素来描述。端口描述的是一个服务访问入口的部署 细节,例如,通过哪个地址来访问,应当使用怎样的消息调用模式来访问等。SOAP 定义了服务请求者和服务提供者之间的消息传输规范。SOAP 用XML 来格式化消 息,用HTTP 来承载消息。通过SOAP, 应用程序可以在网络中进行数据交换和远程过程调用 (Remote Procedure Call, RPC) 。SOAP 主要包括以下4个部分:(1)封装。SOAP封装定义了一个整体框架,用来表示消息中包含什么内容,谁来处理这 些内容,以及这些内容是可选的还是必须的。(2)编码规则。SOAP 编码规则定义了一种序列化的机制,用于交换系统所定义的数据类 型的实例。(3) RPC 表示。SOAP RPC表示定义了一个用来表示远程过程调用和应答的协议。(4)绑定。SOAP 绑定定义了一个使用底层传输协议来完成在节点之间交换SOAP封装的 约定。SOAP 消息基本上是从发送端到接收端的单向传输,但它们常常结合起来执行类似于请求/ 应答的模式。所有的SOAP 消息都使用XML 进行编码。SOAP 消息包括以下三个部分:(1)封装(信封)。封装的元素名是Envelope, 在表示消息的XML 文档中,封装是顶层元 素,在SOAP 消息中必须出现。(2) SOAP 头。SOAP 头的元素名是Header, 提供了向SOAP 消息中添加关于这条SOAP 消息的某些要素的机制。SOAP 定义了少量的属性用来表明这项要素是否可选以及由谁来处理。 SOAP 头在SOAP 消息中可能出现,也可能不出现。如果出现的话,必须是SOAP 封装元素的 第一个直接子元素。(3) SOAP 体。SOAP 体的元素名是Body, 是包含消息的最终接收者想要的信息的容器。 SOAP体在SOAP消息中必须出现且必须是SOAP 封装元素的直接子元素。如果有头元素,则 SOAP体必须直接跟在SOAP头元素之后;如果没有头元素,则SOAP体必须是SOAP 封装元 素的第一个直接子元素。REST是一种只使用HTTP 和XML 进行基于Web通信的技术,可以降低开发的复杂性, 提高系统的可伸缩性。它的简单性和缺少严格配置文件的特性,使它与SOAP 很好地隔离开。 REST 从根本上来说只支持几个操作( POST、GET、PUT 和DELETE), 这些操作适用于所有 的消息。REST 提出了如下一些设计概念和准则:SOA只是一种概念和思想,需要借助于具体的技术和方法来实现它。从本质上来看,SOA 是用本地计算模型来实现一个分布式的计算应用,也有人称这种方法为“本地化设计,分布式 工作”模型。CORBA 、DCOM和 EJB等都属于这种解决方式,也就是说,SOA 最终可以基于这些标准来实现。另外,这些标准分别使用的ORB 、RPC和远程方法调用( Remote Method Invocation,RM I) 等技术,感兴趣的同学可进一步阅读其他书籍学习,此处不再赘述。从逻辑上和高层抽象来看,目前,实现SOA的方法也比较多,其中主流方式有Web Service、企业服务总线和服务注册表。在Web Service(Web服务)的解决方案 中,一共有三种工作角色,其中服务提供者 和服务请求者是必须的,服务注册中心是一个 可选的角色。它们之间的交互和操作构成了 SOA 的一种实现架构,如图12-18所示。(1)服务提供者。服务提供者是服务的 所有者,该角色负责定义并实现服务,使用 WSDL对服务进行详细、准确、规范的描述, 并将该描述发布到服务注册中心,供服务请求(2)服务请求者。服务请求者是服务的使用者,虽然服务面向的是程序,但程序的最终使用 者仍然是用户。从架构的角度看,服务请求者是查找、绑定并调用服务,或与服务进行交互的应 用程序。服务请求者角色可以由浏览器来担当,由人或程序(例如,另外一个服务)来控制。(3)服务注册中心。服务注册中心是连接服务提供者和服务请求者的纽带,服务提供者在 此发布他们的服务描述,而服务请求者在服务注册中心查找他们需要的服务。不过,在某些情 况下,服务注册中心是整个模型中的可选角色。例如,如果使用静态绑定的服务,则服务提供 者可以把描述直接发送给服务请求者。Web Service模型中的操作包括发布、查找和绑定等,可以单次或反复出现。(1)发布。为了使用户能够访问服务,服务提供者需要发布服务描述,以便服务请求者可 以查找它。(2)查找。在查找操作中,服务请求者直接检索服务描述或在服务注册中心查询所要求的 服务类型。对服务请求者而言,可能会在生命周期的两个不同阶段中涉及查找操作,首先是在 设计阶段,为了程序开发而查找服务的接口描述;其次是在运行阶段,为了调用而查找服务的 位置描述。(3)绑定。在绑定操作中,服务请求者使用服务描述中的绑定细节来定位、联系并调用服 务,从而在运行时与服务进行交互。绑定可以分为动态绑定和静态绑定。在动态绑定中,服务 请求者通过服务注册中心查找服务描述,并动态地与服务交互;在静态绑定中,服务请求者已 经与服务提供者达成默契,通过本地文件或其他方式直接与服务进行绑定。在采用Web Service作为SOA的实现技术时,应用系统大致可以分为如下6个层次:底层 传输层、服务通信协议层、服务描述层、服务层、业务流程层和服务注册层。(1)底层传输层。底层传输层主要负责消息的传输机制, HTTP、Java 消息服务( Java Messaging Service, JMS) 和 SMTP都可以作为服务的消息传输协议,其中HTTP 使用最广。(2)服务通信协议层。服务通信协议层的主要功能是描述并定义服务之间进行消息传递所 需的技术标准,常用的标准是SOAP和REST 协议。(3)服务描述层。服务描述层主要以一种统一的方式描述服务的接口与消息交换方式,相 关的标准是WSDL。(4)服务层。服务层的主要功能是将遗留系统进行包装,并通过发布的WSDL 接口描述来 定位和调用处于服务层的服务。(5)业务流程层。业务流程层的主要功能是支持服务发现,服务调用和点到点的服务调用, 并将业务流程从服务的底层调用抽象出来。相关的标准是WSBPEL, 有关WSBPEL的详细知识 见10.5.4小节。(6)服务注册层。服务注册层的主要功能是使服务提供者能够通过WSDL发布服务定义, 并支持服务请求者查找所需的服务信息。相关的标准是UDDI。服务注册表( service registry) 虽然也具有运行时的功能,但主要在SOA 设计时使用。它提 供一个策略执行点( Policy Enforcement Point,PEP), 在这个点上,服务可以在SOA中注册, 从而可以被发现和使用。服务注册表可以包括有关服务和相关构件的配置、依从性和约束文件。 从理论上来说,任何帮助服务注册、发现和查找服务合约、元数据和策略的信息库、数据库、目录或其他节点都可以被认为是一个注册表。大多数商用服务注册产品支持服务注册、服务位(1)服务注册。服务注册是指服务提供者向服务注册表发布服务的功能(服务合约),包 括服务身份、位置、方法、绑定、配置、方案和策略等描述性属性。使用服务注册表实现SOA 时,要限制哪些新服务可以向注册表发布、由谁发布以及谁批准和根据什么条件批准等,以便 使服务能够有序地注册。(2)服务位置。服务位置是帮助服务使用者查询已注册的服务,寻找符合自身要求的服务。 这种查找主要是通过检索服务合约来实现的,在使用服务注册表实现SOA 时,需要规定哪些用 户可以访问服务注册表,以及哪些服务属性可以通过服务注册表进行暴露等。(3)服务绑定。服务使用者利用查找到的服务合约来开发代码,开发的代码将与注册的服 务进行绑定,调用注册的服务,以及与它们实现互动。可以利用集成的开发环境自动将新开发 的服务与不同的新协议、方案和程序间通信所需的其他接口绑定在一起。ESB的概念是从SOA 发展而来的,它是一种为进行连接服务提供的标准化的通信基础结 构,基于开放的标准,为应用提供了一个可靠的、可度量的和高度安全的环境,并可帮助企业 对业务流程进行设计和模拟,对每个业务流程实施控制和跟踪、分析并改进流程和性能。在一个复杂的企业计算环境中,如果服务提供者和服务请求者之间采用直接的端到端的交 互,那么随着企业信息系统的增加和复杂度的提高,系统之间的关联会逐渐变得非常复杂,形 成一个网状结构,这将带来昂贵的系统维护费用,同时也使得IT 基础设施的复用变得困难重 重。ESB 提供了一种基础设施,消除了服务请求者与服务提供者之间的直接连接,使得服务请 求者与服务提供者之间进一步解耦。ESB 是由中间件技术实现并支持SOA的一组基础架构,是传统中间件技术与XML 、Web Service等技术结合的产物,是在整个企业集成架构下的面向服务的企业应用集成机制。具体来 说,ESB 具有以下功能:(1)支持异构环境中的服务、消息和基于事件的交互,并且具有适当的服务级别和可管 理性。(2)通过使用ESB, 可以在几乎不更改代码的情况下,以一种无缝的非侵入方式使现有系 统具有全新的服务接口,并能够在部署环境中支持任何标准。(3)充当缓冲器的ESB ( 负责在诸多服务之间转换业务逻辑和数据格式)与服务逻辑相分离, 从而使不同的系统可以同时使用同一个服务,用不着在系统或数据发生变化时,改动服务代码。(4)在更高的层次, ESB 还提供诸如服务代理和协议转换等功能。允许在多种形式下通过 像HTTP、SOAP和 JMS总线的多种传输方式,主要是以网络服务的形式,为发表、注册、发 现和使用企业服务或界面提供基础设施。(5)提供可配置的消息转换翻译机制和基于消息内容的消息路由服务,传输消息到不同的 目的地。(6) 提供安全和拥有者机制,以保证消息和服务使用的认证、授权和完整性。在企业应用集成方面,与现存的、专有的集成解决方案相比,ESB 具有以下优势:(1)扩展的、基于标准的连接。ESB形成一个基于标准的信息骨架,使得在系统内部和整 个价值链中可以容易地进行异步或同步数据交换。ESB 通过使用XML 、SOAP和其他标准,提 供了更强大的系统连接性。(2)灵活的、服务导向的应用组合。基于SOA,ESB 使复杂的分布式系统(包括跨多个应 用、系统和防火墙的集成方案)能够由以前开发测试过的服务组合而成,使系统具有高度可扩展性。(3)提高复用率,降低成本。按照SOA 方法构建应用,提高了复用率,简化了维护工作, 进而减少了系统总体成本。(4)减少市场反应时间,提高生产率。ESB通过构件和服务复用,按照SOA 的思想简化应 用组合,基于标准的通信、转换和连接来实现这些优点。