构件对象模型概览
<P> </P><P>傅贵 </P>
<P> </P>
<P> 构件技术的产生背景 </P>
<P>计算机软硬件技术特别是网络技术的飞速发展使得人们可以建造功能更强大、结 </P>
<P>构更复杂的应用。这样的一个结果是在应用系统中硬件越来越“瘦小”,而软件 </P>
<P>越来越“肥大”。 </P>
<P> </P>
<P>由于一个应用常常需要异种的计算机硬件平台及其相连的操作系统平台并且其功 </P>
<P>能常常需要不断的扩展,大的应用软件常常需要有跨越多个异种平台的能力并且 </P>
<P>有开放的系统结构。此外,为了提高开发速度和节省开发费用,需要最大限度地 </P>
<P>重用以有代码。因此,当今的应用软件普遍需要有良好的平台兼容性(互操作性 </P>
<P>)、结构开放性、规模可变性(可扩展性)及代码重用能力等。 </P>
<P> </P>
<P>另一方面,在传统的系统开发技术下,庞大的软件使得开发越来越难、开发周期 </P>
<P>越来越长、维护费用越来越高并且功能的扩展危险而难行。应用系统严重依赖于 </P>
<P>操作系统和特定的网络服务因而开放性很差。开发者为每种不同的应用环境(本 </P>
<P>地应用、网络应用、不同操作平台的应用)开发不同的代码。如为解决这些问题 </P>
<P>,国际上成立了许多标准化组织来对系统和处理方式加以标准化,但这只是增强 </P>
<P>软件可操作性和重用性的一种权宜之计,并不能彻底解决问题。在这种情况下, </P>
<P>出现了具有互操作能力和可重用能力的构件对象设计模式和具有分散和联合处理 </P>
<P>能力的开放分布式处理系统。 </P>
<P>构件技术与构件对象模型基本概念 </P>
<P> </P>
<P>概述 </P>
<P>组合软件模型是新一代软件技术发展的标志,它的提出很自然,为了提高软件生 </P>
<P>产力、不草率地开发应用程序、设计开发人员应尽可能地利用可重用的软件构件 </P>
<P>、组装构造新的应用软件系统。追根求源,由软件模块构件组织合成软件的思想 </P>
<P>早在70年代就已提出了,函数就是一种构件,函数通过参数来适应不同应用需求 </P>
<P>的变化,Ada语言的模块package就是一种构件,实现了内部细节掩藏,模块通过 </P>
<P>接口规范说明进行连接和组装,package还提供了类属机制,使模块通过类属参 </P>
<P>数,适应不同应用需求的变化。但是,传统软件系统结构的局限性,以过程为中 </P>
<P>心设计的功能模块,其扩充和复用的能力都较差,对模块进行应用重组的困难很 </P>
<P>多。从80年代开始的面向对象技术的研究,使组合软件又萌发出新的生命力。面 </P>
<P>向对象的软件,以数据为中心设计,对象类既具有模块的封装性和类属等特性, </P>
<P>还具有继承特性,极大地提高了类的可扩充性和可再用能力。对象类较之于传统 </P>
<P>软件的功能模块而另具有的主要优点是: </P>
<P> </P>
<P>易于理解,具有完整的语义特征; </P>
<P>易于重用,可方便地被使用到不同的应用中; </P>
<P>良好的封装性和独立性,相互之间的影响小; </P>
<P>易于扩充和修改,一个对象类的修改不影响其他的对象; </P>
<P>易于构造组装,具有规范的外部接口。 </P>
<P>最早大量使用面向对象技术的是OO(面向对象)的编程语言,它具有上述前三个优 </P>
<P>点。但OO中的对象是源代码级的,它没有也不能统一对象间相互作用的工作机制 </P>
<P>。这意味着它不能克服以下的缺点: </P>
<P> </P>
<P>在OO中只有能提供源代码的对象/类才可被重用, 即它的代码可重用性不能跨越 </P>
<P>编程语言的限制。因此这对实际应用环境来说是一个十分苛刻的要求,使开发人 </P>
<P>员只能利用丰富的软件资源中很少的一部分,并且难以挣脱开发商的束缚。 </P>
<P>兼容性限制到代码级的事实意味着OOP不能解决极其重要的软件修改和升级问题 </P>
<P>。当一个对象被更新或替换时,即使它对外的接口没有被改变,任何使用了该对 </P>
<P>象的代码也都需要被重新编译,与此相关的应用程序必须被重新生成并重新发行 </P>
<P>所有相关的地点。这不仅费时、费钱且容易导致版本交叉的混乱。 </P>
<P> </P>
<P>由于对象没有标准的对外接口,不能使用组装技术来生成应用程序。 </P>
<P>与OO编程语言不同,构件技术是一种更高层次的对象技术:它是独立于语言和面向 </P>
<P>应用程序的, 它只规定构件的外在表现形式,而不关心其内部实现方法;它既可用 </P>
<P>OO编程语言实现,也可用非OO的过程语言实现。只要遵循构件技术的规范, 各个 </P>
<P>软件开发商就可以用自己方便的语言去实现可被重用的构件, 应用程序的开发人 </P>
<P>员就有可能实现在计算机硬件领域早已实现的梦想:挑选构件、组合新的应用软 </P>
<P>件。 </P>
<P> </P>
<P>构件模型由构件(Component)与容器(Container)两种主要成份构成。所谓构件是 </P>
<P>指具有某种些功能的独立软件单元,是一种软件“IC”,它的最重要的特性是可 </P>
<P>重用性。,构件的范围相当广泛,小的构件有像按钮之类的GUI元素,中等规模的有 </P>
<P>如具有列表功能的小应用程序(如Applet), 而大的构件可以是浏览器这样的完整 </P>
<P>的应用系统。构件通过其接口向外界提供功能入口。接口是构件内一组功能的集 </P>
<P>合,它包含的是功能函数的入口,类似于C++中只有虚函数成员的纯虚类。外界 </P>
<P>通过接口引用或接口指针来调用构件内的功能函数。容器类似于装配车间,是一 </P>
<P>种存放相关构件的"器皿",用于安排构件、实现构件间的交互,其形式也是多种多 </P>
<P>样的,如表格(Form)、页面(Page)、框架(Frame)、外壳(Shell)等。另外,容器也 </P>
<P>可以作为另一个容器的构件。 </P>
<P> </P>
<P>推动构件技术发展的最大动力之一是软件重用。软件重用就是利用已有的软件成 </P>
<P>分来构造新的软件,它可以减少软件开发所需的费用和时间,且有利用提高软件的 </P>
<P>可维护性和可靠性。构件软件是目前发展最快的软件重用方式。构件软件解决两 </P>
<P>个重要问题: 一是重用,即构件具有通用的特性,所提供的功能能为多种系统使用 </P>
<P>; 二是互操作,即不同来源的构件能相互协调、通信,共同完成更复杂的功能。 </P>
<P> </P>
<P> </P>
<P>构件软件技术是一种社会化的软件开发方法, 它使得开发者可将由不同语言、不 </P>
<P>同供应商开发的构件组合在一起来构造软件。构件软件和Internet一起被列为目 </P>
<P>前软件产业两个最重要的增长点, 受到了业界的高度重视。许多大公司都先后开 </P>
<P>发出了已被广泛使用的构件,如Microsoft的VBX、OCX及ActiveX控件,Borland </P>
<P>公司的Delphi中数据访问构件等。软件构件的迅速发展使得基本构件装配应用开 </P>
<P>发模型成为一种深入到软业界的新的应用开发模式与开发环境。 </P>
<P> </P>
<P>对象和接口 </P>
<P>在构件对象模型中,对象是一种功能单元,是一种构件。它既可指对象类又可指 </P>
<P>对象类的实例。但此处的对象类与OOP中的对象类又有很大的不同:它有自己唯 </P>
<P>一的标识号(如COM/DCOM中的CLSID)。对象常常以独立的DLL或EXE的形式存在 </P>
<P>,对象之间只能通过标准的接口调用来相互作用。 </P>
<P> </P>
<P>接口是对象中功能相关的一组函数的入口,它类似于C++中只有纯虚成员函数的 </P>
<P>抽象基类,它的指针或引用指向一接口函数表,该函数表包含着接口的功能函数 </P>
<P>的入口。如下图所示: </P>
<P> </P>
<P> </P>
<P> </P>
<P>接口为构件对象模型提供对象间互操作能力。接口的定义也是面向对象或基于对 </P>
<P>象的,它具有继承能力、封装性及多态性等OO特性。 </P>
<P> </P>
<P>对象和接口都有自己唯一的标识。系统通过这两个标识来寻找、识别不同的对象 </P>
<P>及其接口。对象表示必须在系统中进行登记。接口调用由调用者在调用时显式地 </P>
<P>给出,而对象标识则在程序中常常有一个名字映射,调用者在调用对象的接口时 </P>
<P>给出该对象的名字,系统根据对象登记表索引找到该对象。 </P>
<P> </P>
<P>接口定义语言(IDL) </P>
<P> </P>
<P>接口通常都具有自己的定义语言(Interface Definition Language,简称IDL) </P>
<P>。接口定义语言只是为了接口设计的方便而采用的,它可使设计者容易读懂彼此 </P>
<P>的接口设计。IDL编辑器编译IDL代码,生成相应编程语言的头文件及客户代理和 </P>
<P>服务器代理对象。对象及其接口的描述都在IDL头文件中描述。 </P>
<P> </P>
<P> </P>
<P> </P>
<P>分布式构件对象模型 </P>
<P>构件的分布式处理系统模型 </P>
<P> </P>
<P>全球性网络使线上的所有设备和软件成为全球共享的浩瀚的资源,计算机环境也 </P>
<P>从集中式发展到分布式环境,开放式系统的发展使用户能够透明地应用由不同厂 </P>
<P>商制造的不同机型不同平台所组成的异构型计算资源,因此,分布式处理和应用 </P>
<P>集成自然而然地成为人们的共同要求。 </P>
<P> </P>
<P>构件对象模式下的分布式处理是指借助计算机网络将分布在不同地点的构件(即 </P>
<P>对象)组织在一起,进行信息处理的一种方式。分布式处理中的构件可能由不同的 </P>
<P>厂商开发、生产,因而构件之间可能存在不一致的接口;另外,构件之间的通信也 </P>
<P>可能使用不同的协议,有延迟和失败的可能。国际上将这种兼容异质成分的分布 </P>
<P>式处理,称为开放分布式处理(ODP──Open Distributed Processing)。 </P>
<P> </P>
<P>概括地讲,开放分布式处理要达到以下几个方面的透明性: </P>
<P> </P>
<P>(1)存取透明: 隐藏数据表示和调用机制的异同,使用同样的方式存取数据。 </P>
<P> </P>
<P>(2)失败透明: 将出错和恢复事件隐藏在对象内部,以达到容错的目的。 </P>
<P> </P>
<P>(3)位置透明: 隐藏接口的空间位置,用户不需关心接口是哪里提供的。 </P>
<P> </P>
<P>(4)迁移透明: 外界不需要知道系统为使资源均衡而改变对象的位置。 </P>
<P> </P>
<P>(5)持久性透明: 对象里隐藏着所用资源的变化,如处理器资源、存贮资源的冻结 </P>
<P>与解冻。 </P>
<P> </P>
<P>(6)重定位透明: 改变一个接口的位置不影响与之编联的其它接口。 </P>
<P> </P>
<P>(7)复制透明: 为提高性能,能同时有多个行为相同的对象支持某一接口, 而用户 </P>
<P>不需要知道有多个对象存在。 </P>
<P> </P>
<P>(8)提交透明: 一组对象发生作用的次序不影响结果的一致性。 </P>
<P> </P>
<P>挂靠于英国剑桥的APM公司在开放分布式研究方面独执牛耳。他们的"高级网络系 </P>
<P>统结构"(Advanced Networked Systems Architecture,简称ANSA 研究项目),受 </P>
<P>到世界上许多重要公司与研究机构的重视和资助,奠定了开放分布式处理的基础 </P>
<P>。这项研究独立于各种具体的网络、硬件、操作系统和数据库,着力于设计与构 </P>
<P>造灵活的分布式应用。其产品Aware是ANSA 体系结构的一个具体实现。 </P>
<P> </P>
<P>为了使开放分布式处理能达到处理异质构件的能力和上述八个方面的透明性, 国 </P>
<P>际标准化组织(ISO)制订了开放分布式处理的参考模型RM-ODP (Reference Model </P>
<P> Of Open Distributed Processing),该模型的原型是挂靠在英国剑桥的APM公 </P>
<P>司的"高级网络系统结构"(Advanced Networked Systems Architecture, 简称 </P>
<P>ANSA。) 模型分成企业模型、信息处理模型、计算模型、工程模型和技术模型五 </P>
<P>类。这五类模型都与分布式系统的设计相关, 而其中的计算模型和工程模型与分 </P>
<P>布式系统体系结构的关系更为直接。计算模型主要研究客户/服务器结构及其对 </P>
<P>象所提供和享用的服务(Service)。 工程模型主要研究系统资源的分配以及如何 </P>
<P>用工程模型对象来支持计算模型对象。技术模型被用来实现工程模型对象到计算 </P>
<P>模型对象的映射, 它描述了如何利用各个本地操作系统中的进程映射和进程管理 </P>
<P>来具体实现上述映射。 </P>
<P> </P>
<P>1. 计算模型 </P>
<P> </P>
<P>计算模型的核心内容是服务。提供服务和接受服务的双方分别为服务器和客户端 </P>
<P>, 而对象(或构件)则是服务器和客户端的组成部分。一个对象可能是一个以上服 </P>
<P>务的提供者或使用者; 对象是经过封装、独立存在的, 一个对象可以被安装、升 </P>
<P>级、替换或重定位, 而与其它对象无关。 </P>
<P> </P>
<P>服务的提供与使用通过接口来体现, 即接口是提供服务的基本单元。 </P>
<P> </P>
<P>服务可分为两类, 即应用服务和体系结构服务。前者是系统所要完成的特定的任 </P>
<P>务; 后者是指各种任务都要涉及到的服务, 例如, 在一个分布式系统中登记或查 </P>
<P>询一种应用服务, 对使用权限进行控制以及其它的接口管理服务等。"交易 </P>
<P>(Trading)"是最典型的体系结构服务, 它通过系统拥有的目录结构来记录服务器 </P>
<P>对象所提供的服务; 另一方面,客户对象也通过"交易"来寻找所需的服务。提供 </P>
<P>这种"交易"服务的对象被称为"交易器(Trader)"。 </P>
<P> </P>
<P>对象的通信是通过传递接口引用(Interface Reference)进行的。接口引用对应 </P>
<P>用程序来说, 是一个网络指针, 指向提供服务的对象; 从面向对象的角度看, 接 </P>
<P>口引用就是接口实例的索引。接口引用可由一个程序自由地传给另一个程序,这 </P>
<P>也就把使用某种服务的能力传递给了对方。 </P>
<P> </P>
<P>一个对象可以在"交易器"中登记它所提供的服务, 也可以从"交易器"中查找所需 </P>
<P>要的服务, 所有的工程模型对象都清楚"交易器"对象的位置,并可以与之连结,这 </P>
<P>使得客户端与服务器的对象之间可以实现动态联编(Binding)。 </P>
<P> </P>
<P>除了登记和查询服务之外, "交易器"还提供了许多设施使管理员可以进行"交易 </P>
<P>器"内部的组织。例如,"交易器"提供了撤除接口引用、释放资源和关闭"交易器 </P>
<P>"的接口, 它可以给接口引用附加不同的空间位置属性和引用限定, 与接口引用 </P>
<P>名称一起提供给应用程序, 以便于接口的使用。"交易器"还可以优化服务, 即在 </P>
<P>某个服务对象繁忙的时侯,启动包含相同服务的其它对象来满足客户端的要求。 </P>
<P>另外,"交易器"还可以做为其它"交易器"上服务的代理,或与其它"交易器"通过桥 </P>
<P>接联合成"交易器"群,沟通各个应用领域。 </P>
<P> </P>
<P>一个计算模型对象可以有多个接口, 每个接口可称为一种接口类型。不同的接口 </P>
<P>类型提供的操作(或服务)可以相同,也可以不同。它们之间的兼容性可形成父子 </P>
<P>关系,利用这种关系可以优化服务。是否公布某个接口, 供外界使用完全由应用 </P>
<P>程序设计者来决定。 </P>
<P> </P>
<P>2. 工程模型 </P>
<P> </P>
<P>工程模型中的主要概念是"节点(Node)"、"核(Nucleus)"和"封壳(Capsule)"。 </P>
<P> </P>
<P> </P>
<P>一个"节点"可以指一台计算机、一个操作系统进程或一台模拟机, 也可以是由分 </P>
<P>布式操作系统管理的计算机网络, 在不同的场合"节点"有不同的粒度。一个"节 </P>
<P>点"的资源由一个称为"核"的工程模型对象来管理, "核"把资源赋于工程模型对 </P>
<P>象, 使工程模型对象成为一个自治的操作单元(或单独的地址空间), 我们称之为 </P>
<P>"封壳"。因而,一个支持多进程的"节点",如Unix, 可以支持多个"封壳", 而 </P>
<P>MS-DOS只有一个"封壳"。 </P>
<P> </P>
<P>"核"带给"封壳"的能力包括: </P>
<P> </P>
<P>(1)"封壳"是一个受保护的地址空间,其操作即使失败也不会影响到其它的"封壳 </P>
<P>"。 </P>
<P> </P>
<P>(2)允许在"封壳"内对并发活动进行控制。 </P>
<P> </P>
<P>(3)可与其它"封壳"进行通信。 </P>
<P> </P>
<P>(4)保留交互中的状态。 </P>
<P> </P>
<P>(5)构筑其它"封壳"的能力。 </P>
<P> </P>
<P>"核"所提供的资源包括任务(Task)、线程(Thread)、事件同步机制、套接字 </P>
<P>(Socket)、接头(Plug)、通道(Channel)、历程(Session)和接口引用等。 </P>
<P> </P>
<P>任务是"封壳"中由一串操作形成的独立的执行路程; 线程是虚拟的处理器, 它与 </P>
<P>任务编联并为任务提供所需的资源。支持多任务的"封壳"必定支持多线程。事件 </P>
<P>同步机制包括事件计数器(Event Counter)与顺序器(Sequencer), 用于对多个线 </P>
<P>程进行同步。套接字、通道、历程等用于进行"封壳"之间的通信。 </P>
<P> </P>
<P>一个工程模型对象是可以分布、激活、湮灭、转移的最小单元, 是编译了的计算 </P>
<P>模型对象。 由于可以把一个程序编译成一个单元, 也可以就单独的对象分别编 </P>
<P>译, 因此, 一个工程模型对象就是一个或多个运行时的计算模型对象。工程模型 </P>
<P>对象并不具备前面提到的透明性。透明性是在编译计算模型对象, 把透明服务加 </P>
<P>到附加操作与交互状态中而达到的。根据不同的需要可选择不同的透明性。 </P>
<P> </P>
<P> </P>
<P> </P>
<P>构件对象模型系统的典型结构 </P>
<P> </P>
<P>一构件对象模型系统的结构常可分为上、中、下三层,或可称之为基本程序结构 </P>
<P>、远程结构和线路协议(wire protocol)结构。如图所示: </P>
<P> </P>
<P> </P>
<P> </P>
<P> </P>
<P>客户代理(Client Proxy)和 对象代理(Object Proxy)是由接口语言定义的 </P>
<P>代码,它们分别居留在客户进程空间和服务器的进程空间,两着都是用来为接口 </P>
<P>参数的传递作准备工作。客户代理被用来按线路协议的要求将对一接口的调用参 </P>
<P>数打包(称为marshaling过程)或对调用结果解包(称为unmarshaling过程); </P>
<P>对象代理则对接口的调用参数和调用结果分别实施unmarshaling过程和 </P>
<P>marshaling过程。运行库被用来支持客户与对象间的通信,并为这种通信提供空 </P>
<P>间透明性,包括本地进程间的透明和远程透明。线路协议层被用来运载接口调用 </P>
<P>参数和调用结果。 </P>
<P> </P>
<P>当客户发出对一对象的接口调用后,客户所在机器的运行库1负责寻找该对象所 </P>
<P>在的位置并将具体实施该调用。当该对象为远程对象时,运行库1通过线路协议 </P>
<P>层将调用参数传输到该对象所在机器的构件运行库2,通知运行库2实施本调用, </P>
<P>运行库2将调用结果返回到运行库1,由运行库1将调用结果送给客户。在此过程 </P>
<P>中,如果远程对象处于非活动状态,则运行库2将之激活。 </P>
<P> </P>
<P>构件对象模型结构中的客户/服务器模型 </P>
<P> </P>
<P>在接口的调用过程中,调用者(应用程序或对象)充当客户的角色,而被调用的 </P>
<P>接口所属的对象则相当于服务器。 客户应用对接口的调用必须经与运行库的参 </P>
<P>与,运行库的作用即是三层客户服务器结构中的中间层所起的作用,因此如下图 </P>
<P>所示,客户应用──运行库──服务器组成了三层结构的客户/服务器模型。 </P>
<P> </P>
<P> </P>
<P> </P>
<P> </P>
<P> </P>
<P>构件对象模型的技术规范 </P>
<P> </P>
<P>目前构件与开放分布式系统模型理论已经在实际中得到了越来越广泛的应用。当 </P>
<P>前应用较多的有以下三种技术规范或体系结构:一曰CORBA(Common Object </P>
<P>Request Broker Architect)、二为COM/DCOM(Component Object Model / </P>
<P>Distributed Component Object Model)、三称Java Beans。 除这三者之外, </P>
<P>以下规范也可被用来构造分布式构件系统: </P>
<P> </P>
<P>OSF的DCE(Distributed Computing Enviroment) </P>
<P>远程过程调用-RPC (remote procedure calls) </P>
<P>命名管道(Named Pipe)通讯 </P>
<P>基于共享内存的系统 </P>
<P>套接字(Socket)编程 </P>
<P>消息排队(Message Queuing) </P>
<P>其他进程间通讯机制 </P>
<P>数据库表、触发器和轮询(polling) </P>
<P>CORBA是由OMG(Object Management Group)在1989年提出,得到了从IBM、 </P>
<P>Microsoft、Sun、HP、Oracle、 DEC到Iona、Visigenic、VPM等公司的广泛支持 </P>
<P>。COM/DCOM规范是Microsoft在独家发布的构件对象模式技术规范, 而Java </P>
<P>Beans则是SUN公司在1994年12月提出的基于Java的构件模型。</P>
页:
[1]