对李维的《Delphi 5.x分布式多层应用系统篇》中的问题求解(80分)

  • 主题发起人 主题发起人 mycwcgr_bak
  • 开始时间 开始时间
这个问题怎么不结束了???发分吧!
 
多人接受答案了。
 
dcom的陷阱。

如果用dcom开发多层应用,那么使用接口的programmer在远程机器(既是服务器)上建立重型对象的实例的方法是有讲究的。

影响“dcom如何建立一个对象(在哪个进程中?需要新建立进程吗?在哪个线程中?需要新建立线程吗?)来响应client的请求”的因素有这么几个:1对象的intstantiation属性,2对象的线程模型(sta,mta,boath),3类厂(类对象或class factory,都是一个说法)的设计方法。

解释:
对象的intstantiation属性:
dcom环境中的对象都是属于某个进程的。
如果说一个进程只能容纳某个对象的一个实例,那么这个对象的intstantiation属性被称为“single instantiate”
如果说一个进程只能容纳某个对象的多个实例,那么这个对象的intstantiation属性被称为“multiple instantiate”


当client向dcom请求一种接口时 ,dcom发生的事情如下:

if(dcom发现此次请求的是该种接口的第一次请求){
dcom将启动第一个进程xxx,在此进程中制造一个支持该接口的对象,把该对象up cast(类型塑造,转型)成接口,传(marshal,列集)给client。}
else {
if(支持该接口的对象的intstantiation属性被称为“single instantiate”){
dcom将另外启动第一个进程yyy,在此进程中“制造”一个支持该接口的对象,把该对象up cast(类型塑造,转型)成接口,传(marshal,列集)给client}
elseif(支持该接口的对象的intstantiation属性被称为“multiple instantiate”){
dcom将在进程xxx中再次“制造”一个支持该接口的对象,把该对象up cast 成接口,传(marshal,列集)给client}



基本上是这个样子。注意“制造”的方法存在于class factory中。各种framework(vc的atl,delphi 的vcl)各自的都设计了classfactory的实现方式。基本上,client每次请求一个接口,一个对象就会被实例化。client无法指定接口邦定于哪个对象的实例。而“重型对象”
对于这种classfactory默认的“制造”方法是不能容忍的。



接口的线程模型
这个概念实在是个鸡肋。不了解吧不行。因为它是com的专有概念,而且微软把它当作噱头。(作为分布式对象的使用者不应该了解这种多余的底层的琐碎的概念)。想了解,几句话又说不清,搞懂了用处又不大。
线程模型标识了com对象和client两者的线程相容性。如果client的线程模型和com对象的接口的线程模型不相容,那么com的支持环境就会调整client和com对象的接口之间的“交流”。


搞懂了用处又不大。因为多数人都使用atl或vcl开发com对象,这些framework中的设计好 的classfactory隐藏了所有细节,其中包括线程模型的差异如何影响对象的建立。对象的建立方式的差异会影响对象的表现。而在不同framework 中的classfactory中,具有相同的线程模型标识的接口,其对象的建立方式没有规定(甚至同一个framework的不同版本,对具有某种线程模型的接口的对象 有不同的建立方式)。于是线程模型对com对象的影响就非常微妙。

举个极端的例子:delphi4和delphi5中建立dcom 对象,要求intstantiation属性被称为“multiple instantiate”,线程模型为“sta”(单套间线程模型,或 single thread apartment model,都是一个意思)

d4 的classfactory是这么干的:dcom在第一个进程xxx中的主线程中直接create一个对象,把该对象up cast(类型塑造,转型)成接口,传(marshal,列集)给client。

d5中classfactory是这么干的:dcom在第一个进程xxx中新建立一个线程,标识为sta 线程,在该线程中 create一个对象, 把该对象up cast(类型塑造,转型)成接口,传(marshal,列集)给client。

当多个client请求d4 版本的接口时,所有的com对象都在进程xxx的一个sta线程中。所有client对各自接口的调用被sta线程的message loop同步。也就是说一个client的调用会被其他client阻塞。而当多个client请求d5 版本的接口时,所有的com对象都在进程xxx都有各自的sta线程。一个client对自己接口的调用和其他client没有关系。


intstantiation属性决定一个对象在哪个进程中被实例化。而线程模型决定了client如何与com对象交流。dcom没有提到“控制server端所持有的分布式对象的个数”。


 
后退
顶部