全部的优秀程序员都会尽本身的最大努力去使本身所写的程序具备更好的可重用性,由于它可让你快速地写出更加健壮和可升级性的程序。
有两种使代码重用的选择:
1.白盒:最简单的一种,就是把你的程序片拷贝到另外一个文件中。
2.黑盒:它包括把编译过的程序片链接起来。所以客户端能够调用的编译过的黑盒类库就叫做组件。
.Net中也一样为开发者提供了相似于COM的创建和展开组件的方法。开发人员很容易地被这两种以组件为基础的开发模型所迷惑,因此,让咱们来看一看这些不一样的开发方法,以使咱们消除疑惑。
COM的产生
在之前程序设计过程当中,程序员把它们的函数库放在一个叫作目标(Object)文件的单独文件中,在这些文件中,包含了编译过的代码。当程序员要使用一个特别的目标文件的时候,他们把客户程序编译成机器代码,而后依靠动态连接的手段把客户程序联接到目标文件上,最后变成一个单一的可执行文件。这种做法的惟一的好处在于它节省了编译函数库的时间。可是它有许多的缺点,好比因为在每一个单独的可执行文件中都有一个程序库包括在里面,浪费了许多存储空间;对应用程序的维护也是很是困难的,若是在函数库中发现了一个bug,整个可执行文件都要被从新编译和分发。
还有不仅一个的严重的限制在里头,一个客户应用程序必需要和用同一种语言编制的函数库在一块儿才能使用。好比说,一个用QuickBasic写的客户应用程序就不能引用一个用C++写的函数库。
所以,微软公司出品了COM,COM仅仅只是一个规范。无论组件用什么语言写成,只要符合这个COM规范,就能被用任何一种语言写成的客户程序调用。此外,程序员没必要再担忧要去创建一个单一的可执行文件,由于组件是以GUID(Global Unique Identifier全球惟一标识符)来标识的。GUID是一个128位的号码,和一些相关的信息一块儿被放在系统的注册表中,用来惟一标识组件。客户应用程序只在运行期间才动态地创建一个组件的实例,并使用这个组件的功能,所以,只须要一个函数库的拷贝。它的缺点就是你们经常提到?quot;DLL地狱"。这个问题在一个DLL要被一个新版本的DLL所取代时引起。开发者不得不经过关闭全部的客户应用程序的方法(若是不行,还要关闭WWW服务)来达到清除所用对这个组件的引用的目的。有时全部的方法都还起不了做用,那你只好从新启动服务器后才能替换掉老的DLL。
COM+
为了让企业级的应用程序能使用上COM,它必须要有如下的特定的能力。
· 验证能力
· 对象池(Object Pooling)
· 事务处理
· 支持分布式架构
为了使开发者没必要去为他们的组件添加这些能力,微软公司出品了DCOM(Distributed COM分布式COM)和MTS(Microsoft Transaction Server微软事务服务器)。使用这两种技术,开发者就能够把精力用在他们的商业逻辑上,而没必要放在后台的他们的组件上。
DCOM是一个用于分布式的组件之间的通信的RPC(Remote Procedure Call)协议。客户端向一个本地机的代理类发送请求,而后由代理类将这个请求隐含地给安装在远程机器上的"根"类,而后执行结果原路送回给代理类,最后代理类把它们回送给客户端。所以,客户程序的位置彻底与组件的位置无关。DCOM的缺点在于,因为DCOM使用的是一个独立的硬件端口,而不是HTTP协议的80端口,因此在组件间通信的过程当中,必须保证这个端口是开着的。这是一个严重的安全问题。因此DCOM不可以轻易地穿越防火墙。
为了使用MTS,程序员在它们的组件里放置特别的MTS钩子,编译后把他们放在MTS包中。把有关系的组件放在一个单一的包中有它本身的好处。当客户请求一个包中的一个组件的一个实例的时候,MTS确保为这个包创建一个新的专门的线程,一个新的组件实例被创建在这个线程上并被应用事务服务。至于对象池服务和安全服务是否要被创建,那就要看开发者的请求了。
MTS容许相关的做业单元被看成一个事务来对待,这意味着若是全部的做业单元被成功地完成,整个事务就被看成成功地完成,反之若是有一个单元未成功完成,整个事务将被从新轮回。
在客户请求对象和释放对象后,MTS仍保存着这个对象,因此当另外一个客户请求同一个组件的时候,MTS就将保存着的对象交给它。经过这种方式,MTS减小了在服务器源实例化的次数。
MTS容许开发者用安全措施来组装他们的组件,以使其具备识别请求它的服务的客户的能力。这可以确保未经受权的客户不可以使用组件的功能。
MTS以COM+的名义被完整地整合到了微软公司的Windows 2000操做系统中,可是COM+不只仅只有MTS,它还包括一些其它的服务。MSMQ(Microsoft Message Queue Server),一个与MTS一同发布的服务,也被以COM+的名义整合到了Windows 2000中。MSMQ容许服务器端和客户端进行同步的通信。事件服务(Event Service)也被加了进来,它使服务器可以与客户端同步地交流事件的发生。负载平衡服务(Load Balancing)自动地实例化机器上的具备最多资源的服务器上的请求对象。
.NET
.Net提供了一种全新的创建和展开组件的方法。它就是大名鼎鼎的Assemblies。使用COM,开发者必须要在服务器上注册组件,这也就是说,系统注册表中的组件的信息必须被更新。这样作的目的是保证组件的中心位置,以使COM+可以找到合适的组件。使用.Net的Assemblies,装配(Assembly)文件把全部须要的元数据(meta data)都压入一个叫Manifests(名单)的一个特殊的段中。在.Net中,要使assembly对用户有效,只要简单地把他们放在一个目录中就好了。当客户程序请求一个特别的组件的实例的时候,.Net运行期(runtime)在同一个目录搜寻assembly,在找到后,分析其中的manifest,以取得这个组件所提供的类的信息。因为组件的信息是放在manifest里的,因此开发者就没有必要把组件注册到服务器上,所以,就能够容许几个相同的组件安全地共存在一个相同的机器上了。
创建一个.Net assembly并不像创建一个VB6组件,惟一让开发者操心的就是商业逻辑,全部的后台代码所有由.Net运行期产生,并且因为.NET运行期具备碎片收集器的功能,组件没必要担忧它的引用数目(在COM中是靠Iunknown的帮助)。简单地说,在.NET中创建一个assembly比创建一个VB6 COM要简单地多。
纯的.NET assemblies不可以在COM+服务下注册,由于它们是和COM不一样的二进制标准。面对.NET,assemblies的前景相对于COM来讲是"高级的COM"。可是因为当前架构于COM+上的应用程序的可靠性,COM还会持续一段时间。这也许就是微软公司向开发者同时提供开发.NET assemblies和COM的工具的缘由吧。
类型库引入器(Type Library Importer (TLBIMP.exe))工具能够把COM组件封装成.NET,以使之前的东西能够在.NET应用程序中继续使用。
类型库导出器(Type Library Exporter (TLBEXP.exe))工具将.NET组件封装成COM,这个工具也是颇有用的,若是你要用你的.NET assemblies去替换原有的COM组件,就得用到它了。由COM+提供的服务不能被忽略,因此把.NET assemblies封装成COM组件就变得至关重要了。做为一种选择,开发者能够从.NET基础类库中选择更多的功能。程序员