组件技术介绍

组件(component)技术是各种软件重用方法中最重要的一种方法,也是分布式计算和Web服务的基础。网络应用中的软件组件,又被称为中间件(middleware)。
组件技术的应用现在已经十分广泛,从Windows编程中使用的各种控件和公用对话框,到ActiveX控件和DirectX的应用;从微软公司的COM,到Sun公司的JavaBean。其中最流行的组件技术的应用是——客户端的VBX(微软/VB)和服务器端的EJB(Sun/Java)。
在网络及其应用都很发达的今天,对组件服务的需求十分强烈,因此组件技术近年来得到了飞速的发展和广泛的应用。
概述
面向过程的编程重用函数、面向对象的编程重用类、范型编程重用的是算法的源代码,而组件编程则重用特定功能完整的程序模块。
每个组件会提供一些标准且简单的应用接口,允许使用者设置和调整参数和属性。用户可以将不同来源的多个组件有机地结合在一起,快速构成一个符合实际需要(而且价格相对低廉)的复杂(大型)应用程序。
组件区别于一般软件的主要特点,是其重用性(公用/通用)、可定制性(设置参数和属性)、自包容性(模块相对独立,功能相对完整)和互操作性(多个组件可协同工作)。可以简单方便地利用可视化工具来实现组件的集成,也是组件技术一个重要优点。
普通的面向过程和面向对象的编程,一般会生成两种类型的软件——针对特定应用的可执行程序和面向通用编程的API库。前者包含你需要的各种特殊的具体功能,但必须从头到尾自己来创建,其中很多是低层次的重复劳动;后者虽然通用,但是却不能满足你的具体应用的特殊需要。
组件技术提供了第三种途径,它将库的可重用性与特定程序的可定制性结合起来,让用户可以用可重用的组件来定制自己特定的应用程序。所以组件在某些方面类似于“可执行程序”,在另一些方面又类似于“库”。
采用MFC编程,可选的项目类型为:MFC应用程序、MFC DLL和MFC ActiveX控件,刚好对应于上面所讨论的可执行程序、库和组件这三类软件。
使用组件来构造应用程序的工作(组件集成)非常简单,不需要专业程序员,普通用户就可以很快做到。但是设计和创建组件(组件编写)的工作却十分复杂,只有高水平的程序员才有可能完成。这也是为什么VB和Delphi会如此流行的真正理由(组件功能强大,编写又非常简单),同样也是ATL和EJB等(创建组件)编程少有人问津的原因。
1.组件模型
软件组件的核心技术是组件模型,它定义了组件的体系结构、及如何操作此结构并与外部交互。
组件模型的两个基本要素是——组件和容器。模型的组件部分,提供构造组件的模版,是各种组件创建和使用的基础;模型的容器部分,定义了将多个组件结合成有用结构的方法,为组件的结合和交互提供环境支持。

2.中间件
中间件(middleware)是一种软件,它能使处于应用层的各种应用组件之间实现异构网络平台上的协同工作。它是组件技术的最重要方面,也是分布式计算和Web服务等网络应用技术的主要组成部分。
    

    中间件定义
中间件一般由执行环境和应用开发工具两部分组成,可以分成事务处理中间件、消息中间件和分布式中间件等三种类型。 

组件标准

组件应用的基础是标准,没有统一的接口描述、没有规范的组件通信、没有标准的对象请求和远程调用,就没有组件应用的可能。目前的主要标准有CORBA(国际通用)、EJB(Sun的Java)、COM和CLR(Microsoft的Windows和.NET)。
1.CORBA
最早而且最权威的组件标准是CORBA (Common Object Request Broker Architecture公共对象请求代理体系结构),它由OMG所制定的,1991年10月推出1.0版、1996年8月推出2.0、2002年7月推出3.0,目前的最新标准为2004年3月12日推出的CORBA 3.0.3版。
OMG(Object Management Group对象管理组,http://www.omg.org/)是一个开放型非赢利组织,负责制定和维护协同企业应用的计算机工业规范。OMG是1989年4月由3COM、Apple、美国航空、佳能、DG、HP、IBM、Philips、Unisys和Sun等11个公司所创建的,后来发展到800多个公司、大学和国际组织,包括Adobe、AT&T、Borland、CA、加州大学、富士通、HP、IBM、MIT、NEC、Oracle、Sun、东芝、东京大学、清华大学、W3C等。(注意,Intel和Microsoft并没有参加)。OMG制定的其他标准还有:UML(Unified Modeling Language统一建模语言)和IDL(Interface Definition Language接口定义语言)等。
CORBA是一种独立于语言的分布式对象模型,其核心是ORB(Object Request Broker对象请求代理),对象的接口用IDL描述,在各个对象之间采用IIOP(Internet Inter-ORB Protocal因特网ORB交互协议)进行通信。
2.EJB
Sun公司于1997年在Java的JDK 1.1中引入了JavaBean组件技术,后来又于2000年随J2EE(Java 2 Platform, Enterprise Edition,Java 2平台企业版)引入服务器端的组件技术EJB(Enterprise JavaBeans企业爪哇豆)和网页编程工具JSP(JavaServer Page, Java服务器网页)。至此,Java成为了一种功能完备的分布式计算环境。这对(一心想进入利润丰厚的服务器端网络应用软件领域的)微软公司,造成了极大的威胁。

JavaBean是一种可复用的平台独立的软件组件,开发者可以在软件构造器工具(如网页构造器、可视化应用程序构造器、GUI设计器、服务器应用程序构造器等)中对其直接进行可视化操作。而EJB则是用于开发企业级的服务器端应用程序的JavaBean组件,可以分为会话bean(维护会话)、实体bean(处理事务)和消息bean(提供异步消息机制)等三种类型。
JavaBean的接口采用标准的IDL定义,在各个EJB之间采用RMI(Remote Method Invocation远程方法调用)进行通信,而且J2EE还为EJB与CORBA的集成提供了适配器和RMI的扩展——RMI-IIOP,可以用于EJB与CORBA对象之间进行通信。而对数据库的访问,采用的则是JDBC(Java DataBase Connection,Java数据库连接)。
3.COM / .NET
COM(Component Object Model组件对象模型)是微软公司于1993年提出的一种组件技术,是软件对象组件之间相互通信的一种方式和规范,它是一种平台无关、语言中立、位置透明、支持网络的中间件技术。

COM是OLE(Object Linking and Embedding对象链接和嵌入)的发展(而OLE又是DLL [Dynamic Link Libraries动态链接库]的发展),DCOM(Distributed COM分布式COM,1996年)和COM+(DCOM+管理,1999年)则是COM的发展。ActiveX控件是COM的具体应用(如VBX和DirectX都是基于ActiveX的)。ATL(Active Template Library活动模板库)是开发COM的主要工具,也可以用MFC来直接开发COM,但是非常复杂。

作为组件技术的进一步发展,微软公司又于2002年推出了.NET框架,其中的核心技术就是用来代替COM组件功能的CLR(Common Language Runtime公共语言运行库),可采用各种编程语言,利用托管代码来访问(例如C#、VB、MC++),使用的是.NET的框架类库FCL(Framework Class Library)
微软公司的各种组件技术之间的关系与发展可以参见下图:


下面分别对这几种组件技术加以简单的介绍:
1)DLL
DLL(Dynamic Link Libraries动态链接库)还不能算组件技术,但它是软件重用的鼻祖。

普通的静态链接库,虽然也能做到代码共享,但是只能是在编译链接阶段。在运行时,程序调用的是已经链接到自己程序内的库函数。如果每个程序都包含所有用到的公共库函数,则这是很大的浪费,即增加了链接器的负担,也增大了可执行程序的大小,还加大了内存的消耗。
而DLL采用动态链接,对公用的库函数,系统只有一个拷贝(位于系统目录的*.DLL文件),而且只有在应用程序真正调用时,才加载到内存。在内存中的库函数,也只有一个拷贝,可供所有运行的程序调用。当再也没有程序需要调用它时,系统会自动将其卸载,并释放其所占用的内存空间。
由于应用程序是通过系统来调用动态链接库的,因此每个DLL都有一个类似于main的入口函数。在DLL中,供外部应用程序调用的库函数叫做导出函数,而只是被DLL内部调用的库函数则叫做内部函数。导出函数在客户端叫做导入函数。
2)OLE
OLE(Object Linking and Embedding对象链接和嵌入)是微软公司于1991年推出的一种简单的组件技术,它允许Windows中的程序相互之间进行合作——一个(客户)程序调用另一个(服务器)程序,以完成特定的功能。而且客户/主程序的界面不变,就似将服务器程序嵌入到客户程序中一样。

实际上,OLE是一套可扩充的协议(OLECLI.DLL和OLESVR.DLL),能使客户和服务器应用程序通过一组DLL彼此进行通信。1993年随VC1.0又推出OLE2.0,对1.0版进行了若干改进,使客户和服务器的结合更加紧密,还允许服务器继承客户的主菜单,使得用户感觉不到在不同应用之间的切换,并且提供了C++的开发接口(1.0版只支持C语言开发)。

OLE使用DDE(Dynamic Data Exchange动态数据交换)作为客户和服务器应用程序间通信的传输机制。

3)COM
OLE 1.0实际上只是一种复合文档,而OLE 2.0已经具有标准组件的特性了,显然它是受了CORBA的影响。所以从OLE 1.0到OLE 2.0,是微软公司在组件技术上的一次飞跃。这时,OLE的名称就有一些名不副实了,因此,在增加了一些功能和规范之后,微软公司于1993年在OLE 2.0的基础上又推出了COM,用来替代原有的OLE。这样一来,OLE就不再是一种独立的组件技术,而只是COM技术在链接和嵌入方面的一个具体应用。而1996年3月推出的ActiveX控件,也只是COM的一个具体应用,它是用来替代原有的VBX控件的。

COM(Component Object Model组件对象模型)的核心是一组组件对象间交互的规范,它定义了组件对象如何与其使用者通过二进制接口标准进行交互,COM的接口是组件的球类型纽带。

除了规范之外,COM还是一个称为COM库的实现,它包括若干API函数,用于COM程序的创建。COM还提供定位服务的实现,可以根据系统注册表,从一个类标识(CLSID)来确定组件的位置。

COM采用自己的IDL来描述组件的接口(interface),支持多接口一解决版本兼容问题。COM为所有组件定义了一个共同的父接口IUnknown。GUID 是一个 128 位整数(16 字节),COM将其用于计算机和网络的唯一标识符。

除了基本规范和系统实现之外,COM的构成还包括永久存储、绰号(moniker智能命名/标记)和统一数据转移(UDT = Uniform Data Transfer)三个核心的操作系统部件。
在COM模型中,所有将CLSID传递给COM并获得实例化的对象,都被称为COM客户(程序)。最简单的实例化方式,是调用COM函数CoCreateInstance。也可以通过调用CoGetClassObject函数来为CLSID获得类工厂(Class Factory)对象的接口指针。


与COM客户程序相比,COM服务器在于实现类工厂和其生产的对象类,并将工厂提供给COM使用。


4)DCOM

DCOM(Distributed COM,分布式COM)是COM的网络化。COM具有进程透明性,组件对象和客户代码不必考虑调用传递的细节,只须按照普通函数方式进行调用即可。而DCOM将COM的进程透明性扩展为位置透明性,形成分布式的组件对象模型。


COM组件有两种进程模型:进程内组件和进程外组件。由于本地进程外组件与客户运行在不同的进程空间,所以客户程序对组件对象的调用,并不是直接进行的,而是用到了操作系统支持的一些跨进程通信方法,主要有OSF(Open Software Foundation开放软件基金会,现在改为Open Group[开放小组http://www.opengroup.org/])开发的DCE RPC(Distributed Computing Environment 分布式计算环境Remote Procedure Call 远程过程调用)和LPC(Local Procedure Calls本地过程调用)。

为了将组件服务延伸到网络,DCOM建立在自己的网络协议上,并通过SCM(Service Control Manager服务控制管理器)来创建远程对象。

COM的"ORB"结构

 
5)COM+
COM+是COM-based services and technologies(基于COM的服务与技术)的简称,+表示将COM组件技术和MTS(Microsoft Transaction Server微软事务服务器)应用程序主机技术结合在一起。它是一个面向应用的高级COM运行环境,它在COM基础上实现了许多面向企业应用的分布式应用程序所需要的服务。COM+是1999年随Windows 2000推出的。

COM+是Windows DNA(Distributed interNet Application [Architecture]分布式网间应用程序[体系结构])框架的重要组成部分。DNA为Windows环境下开发分布式应用程序提供了工具和框架,而COM+则是DNA的中间件技术和粘结剂。COM+会自动处理不同的编程任务,诸如资源集池、分离应用程序、事件发布、预定和分布式事务。

  


其中:

IE = Internet Explorer因特网探索者(微软的网页浏览器)

HTTP = Hypertext Transfer Protocol超文本传输协议(W3C制定的万维网的数据传输协议)

IIS = Internet Information Services因特网信息服务(微软的因特网服务器平台组件)

ASP = Active Server Page动态服务器网页(微软的Web服务器端的动态网页脚本语言)

Visual InterDev = VS中针对因特网应用程序的专用开发工具(使用ASP)

MTS = Microsoft Transaction Server微软事务服务器(协调组件和数据库、负责管理资源的缓存和共享、实现可伸缩性,通常被用作组件的容器,可以视为组件管理器或代理程序)

MSMQ = Microsoft Message Queue Server微软信息队列服务器(负责复杂的、涉及发送和接收、同步和异步之信息获取的协调工作)

ADO = ActiveX Data Objects,ActiveX数据对象(微软的关系数据库访问组件)

SQL = Structured Query Language结构化查询语言(关系数据库的通用查询语言,国际标准)

6).NET / CLR
.NET的核心是CLR,它可以视为是COM技术的继承和发展,它解决了COM组件模型中存在的主要问题。
 
Web服务
框架和库
(ASP.NET、ADO.NET、Windows窗体)
交互标准
(SOAP、WSDL)
开发工具
(Visual Studio .NET/2005)
组件模型
对象模型和CLS
CLR
.NET框架的分层结构
(1)COM的缺陷
COM(含DCOM和COM+)组件技术存在许多问题,其中有一些是关键的,有的甚至是致命的。
组件技术主要强调在独立开发和部署的程序之间的一套约定(contract),COM则是微软公司将这些约定规范化的首次尝试。COM既能作为设计范例(paradigm)(它将组件的约定,表示为类型定义),也可用作支持平台技术。作为前者,COM编程模型相当成功;但是后者却存在诸多问题,正是由于缺乏稳固的平台技术,COM时代面临着终结。
组件间的约定,纯粹是通过用户与组件之间的语义保证和假设的形式来表示的。但是,仍需要定义某种形式来表示语义,专业的做法是——采用可编程的类型定义,以及描述这些类型定义的人工可读文档。
COM用类型的形式表示组件约定,但是该约定存在如下两个关键问题,使得其对语义的表示并不是最优的。
1.约定的描述:
COM没有定义约定的交换格式,即COM规范所约定的类型定义,必须通过完全是COM之外的某种技术来进行交互。微软定义和支持的COM交换格式有两个——IDL(Interface Definition Language接口语言定义)和TLB(Type LiBrary类型库),但是这两种格式并不是同构的,其中也没有哪种格式是权威的或标准的。
另外,COM的描述约定方式,至少还存在两个其他的关键问题:
① COM缺乏对组件依赖性的描述。因此,没有办法来解析COM组件(或者其约定的定义),也不能确定它所需要的其他组件,从而无法保证它的正确运行。由于缺少相关信息,使得部署基于COM的应用程序,很难确定它需要哪些DLL,也不能静态确定所需要的是哪个版本的组件,这让对版本问题的诊断变得极其复杂;

② COM约定的描述格式缺乏扩展性。IDL是基于文本的,极少随组件部署,通常只有C++程序员才会使用。但是,在MTS下开发企业应用的C++程序员很少,这使得IDL约定用处不大。TLB在扩展性方面存在缺陷,而且VB与TLB/MTS之间被隔离开来,这最终导致了TLB的没落。
2.约定的工作方式:
COM组件的约定是基于类型描述的,所采用的类型系统是C++的可移植子集。而且COM对组件的约定是物理的(二进制约定)。它要求:每个方法都具有精确的虚函数表vtable偏移量、每个被传递的参数在堆栈规则中都有明确的偏移量、对象引用采用接口指针的明确格式、使用规定的分配器进行被调用这内存分配。
就底层技术而言,COM组件的约定,最终只是在内存中形成堆栈结构的协议,根本没有(按组件所要求的那样来)描述语义内容。二进制的物理约定,过度关心细节,使COM难于使用和开发。尤其在针对COM组件的版本控制问题上,物理性约定所产生的问题就更大了。这使得COM组件,难以进行语义修改和版本升级。
COM组件的约定定义的精确性,产生了高效的代码,但这却是以难以接受的不可靠性和开发使用及扩展升级的困难与复杂性为代价的。
(2)CLR与CLI
为了解决COM所存在的这些问题,微软公司的COM和MTS小组,计划开发一个新的组件平台。开始时叫COM3或COM+ 2.0,后来又叫COR(Component Object Runtime组件对象运行时)和URT(Universal Runtime通用运行时),最后才被命名为CLR(Common Language Runtime公共语言运行时[库/层])。它是现在(由微软提交的)成为国际标准的CLI(Common Language Infrastructure公共语言基础结构)在Windows平台上的一种具体实现。

CLI是针对可执行代码格式、以及能执行该代码的运行时环境的一种规范。CLI标准包含如下几个主要组成部分:
    CTS(Common Type System公共类型系统)——被编译器、工具和CLI本身所共用的一种统一类型系统。 它是一个模型,定义了在声明、使用和管理类型时,CLI应遵循的规则。CTS建立了一个框架,使跨语言集成、类型安全和高性能的代码执行成为可能;

    CLS(Common Language Specification公共语言规范)——语言设计者和框架(类库)设计者之间的一种协定(agreement)。它指定了CTS的一个子集和一个用法常规(usage conventions)集;

     metadata(元数据)——描述和引用CTS所定义类型的数据。元数据被以一种独立于任何特定的程序设计语言的方式存储。从而,元数据为操作程序的工具(如编译器和调试器)之间,以及这些工具和VES之间提供了一种公共交换机制。

    VES(Virtual Execution System虚拟执行系统)——该系统实现和实施CTS模型。VES负责装入和运行为CLI编写的程序。它在运行时,利用元数据将分开产生的模型连接在一起,并为执行托管代码和数据提供所需要的服务。VES也被称为执行引擎;

     CIL(Common Intermediate Language公共中间语言)——可被VES理解的指令集,也被称为MSIL(微软IL)。

 
程序集(Assembly,装配/汇编)就是CLR中的组件,它是一种功能上不可分割的逻辑单元,由一个或多个模块(module,DLL或EXE文件)组成。大多数程序集就是一个DLL,所以程序集也被称为“托管DLL”。
每个程序集中有一个程序清单(manifest),它包含了程序集内所有模块和其他文件的信息(如程序集的名称、版本号、文化和语言、程序集包含的所有文件列表、程序集所依赖的其他程序集等)。
程序集中自然包含了若干CLR类的(MSIL中间语言)代码,同时还包含了这些类的元数据。元数据(metadata)描述模块中类型的相关信息,如类型的名称、类型的可见性(public或assembly)、基类、实现的接口和方法、暴露的属性、提供的事件等。

(3)CLR与COM
与COM相比,CLR的组件技术有了质的飞跃,前面提到的各种COM问题都迎刃而解、一扫而光。

相同点——约定(类型)

与COM平台一样,CLR也注意组件间的约定,而且这些约定也是基于类型的(注意,组件技术里的类型是广义的,除了包括字符、布尔、整数和浮点数等基本数据类型之外,还包括类、结构、接口、串、数组、枚举、委托[delegate,指向方法和函数的安全指针,用于事件处理和回调]等高级结构类型)。
 
   不同点1——约定的描述(元数据)

但是与COM(没有标准格式来描述约定)不同的是,CLR有完全规范的格式来描述组件之间的约定——元数据(metadata)。CLR的元数据是机器可读的,其格式是公开的、国际标准化的、完全规范的。CLR还提供了读写元数据的实用工具,使用者不需要了解元数据的底层文件格式。
不像COM的元数据(IDL和TLB)难以定制和扩展;而且其元数据中又缺少依赖和版本信息,使得对组件的部署和版本的控制都十分困难;另外,COM元数据的存在是可选的,而且经常会被忽略掉,这对组件应用的构建会造成很多问题。
CLR通过定制(本身就是强类型的)特性(attribute),使其元数据可以达到清晰容易的可扩展性。CLR元数据中还包括组件的依赖关系和版本信息,从而允许使用新技术来处理版本控制问题。另外,CLR元数据的存在是强制性的,部署或加载组件都必须访问元数据。因此,构建基于CLR的基础架构和各种工具,显然要比COM容易的多。
 
   不同点2——约定的类别(逻辑结构)

CLR约定与COM约定的第二个主要差别,是约定本身的特性。
在COM中,组件的(二进制物理)约定隐含了:堆栈约定、虚函数表和(作为方法参数传递的)数据结构在内存中的表示形式。
在CLR中,约定被描述为类型的逻辑结构,而不是物理的二进制格式。因此,在CLR的约定中,并没有暗示访问字段和方法的精确代码顺序。所以,在考虑虚方法布局、堆栈规则、对齐方式、以及参数传递方式时,CLR具有极大的灵活性。CLR是通过名字和签名来引用字段与方法,而不是偏移量。这样,CLR就避免了困扰COM的声明顺序问题,组件成员的实际地址/偏移量,需要等到运行时在类型被加载及初始化时,才能够确定。另外,CLR版本的改变(如从2002年1.0到2003年的1.1,再到2005年的2.0),也不会带来组件的重新编译。
 
   不同点3——CIL

实现数据表示形式和方法地址的虚拟化,需要延时对约定的物理方面(如方法表和字段偏移量等)的解析,这就要求组件中不含具体的机器代码。基于CLR的组件,通过采用CIL(Common Intermediate Language公共中间语言)而实现了这一要求。
CIL是一组与处理器无关的指令集,它具有抽象能力——将与机器代码密切关联的物理数据的表示形式抽象出来。CIL使用的操作码在访问字段和调用方法时,不再使用绝对地址和偏移量,而是利用元数据进行基于名字和签名的引用。
CIL会在(第一次被)执行前被翻译成本地的机器语言,CLR执行的是由CIL生成的本地代码。而CLR在CIL杯翻译成本机代码之前,是不会解析其物理绑定的细节的。由于翻译工作是在部署机器上进行的,所以,组件所需的外部类型定义,将与部署机器上的某个类型匹配,而不是开发者的机器。这极大减少了跨组件约定的不可靠性,同时又不会降低代码的运行性能。
另外,由于CIL到机器代码的翻译,发生在部署的机器上。所以,任何用到的待定处理器布局或对齐规则,都将与(代码将在其上面运行的)目标处理器架构相匹配。现在,软件正面临着一次重大的处理器迁移,即从IA-32/Pentium和AMD32架构向IA-64/Itanium和AMD64架构的发展。对于这次升级,CLR显得尤为重要。
 
  COM向CLR过渡

鉴于COM技术已经被使用多年,有许多现存的资源,程序员和用户也不可能一下子就全部完全转换到.NET环境。因此,微软公司也允许在CLR环境中继续使用COM/DCOM/ COM+和DNA,这可以通过.NET框架的 System.EnterpriseServices 命名空间来进行。
但是鉴于与COM相比,CLR组件所具有的无比优越性。COM技术必然会走向灭亡,而.NET的CLR终将取而代之。


作者:touzani 
来源:CSDN 
原文:https://blog.csdn.net/touzani/article/details/1619472 
版权声明:本文为博主原创文章,转载请附上博文链接!

你可能感兴趣的:(控件开发,组件,COM,DLL,.NET,中间件)