woaidongmao

文章均收录自他人博客,但不喜标题前加-[转贴],因其丑陋,见谅!~
随笔 - 1469, 文章 - 0, 评论 - 661, 引用 - 0
数据加载中……

COM 类工厂有必要存在吗?

1. IClassFactory 的用途

http://www.80diy.com/home/20041120/19/3572410.html 看到几段关于COM 的类厂的话,

"""
类厂用来抽象组件的create过程,客户不需要知道组件的详细情况,也不需要知道类厂的详细情况,只要知道CoCreateInstance可以创建组件即可。而CoCreateInstance内部调用DllGetClassObject来生成该组件的类厂,由于类厂有组件的作者撰写,所以对组件类可谓知根知底,由类厂来生成组件完全行得通,这样客户和组件就进一步划分,客户只能查询该组件是否支持某借口,而对组件的其他情况一无所知,这样的划分可以使组件和客户间的耦合更小。
"""

"""
组件如果将某接口的全部方法都实现了,就称该组件支持某接口,com并没有规定组件和接口之间是虚函数继承的关系,只是在c++中以这种方法来实现最好而已。  
IClassFactory
说穿了就是专门构造组件的类,这样做是为了抽象,因为客户没有必要知道组件是什么,如果由客户直接构造组件,客户势必要知道组件的信息,com就失去了它的意义了,所以,规定了一个类厂(支持IClassFactory接口),每个组件的类厂都很清楚并且也只清楚该组件的信息,而客户只需要调用com库函数CoCreateInstance就可以了。  
下面是流程图:  
  CoCreateInstance -> CoGetClassObject -> DllGetClassObject -> new ClassFactory -> IClassFactory::CreateInstance() -> new Component
"""

并且在 http://www.codeproject.com/com/comintro2.asp 也看到几段话

"""
每次实现组件对象类的时候,都要写一个旁类负责创建第一个组件对象类的实例。这个旁类就叫这个组件对象类的类工厂(class factory),其唯一目的是创建COM对象。之所以要一个类工厂,是因为语言无关的缘故。COM本身并不创建对象,因为它不是独立于语言的也不是独立于实现的。
当某个客户端想要创建一个COM对象时,COM库就从COM服务器请求类工厂。然后类工厂创建COM对象并将它返回客户端。它们的通讯机制由函数DllGetClassObject()来提供。
"""

<COM 技术内幕> , 对类厂的引入也有描述.
主要是:
a.
在面向对象系统中, 对象创建是非常重要的, 因为要使用它必须先创建它. 所以尽可能灵活的创建对象(component)
b.
CoCreateInstance 创建对象过程是: 传给一共CLSID, 然后创建成相应组件, 并返回所请求的指针. 其弊端在于无法提供给客户一种控制对象创建过程的方法. (问题关键不在初始化, 而是控制创建对象过程)
c. IClassFactory2
成批的调用接口.


2.
参考CoCreateInstance 的实现过程:
CoCreateInstance -> CoGetClassObject -[
系统|组件代码]-> DllGetClassObject -> new ClassFactory -> IClassFactory::CreateInstance() -> new Component

因为 DllGetClassObject -> new ClassFactory -> IClassFactory::CreateInstance() -> new Component 都是组件所来实现的, 而系统调用 CoCreateInstance 所提供的参数, 和通过自己使用IClassFactory 来创建Component 的参数是没有变化的, 所以如果省略 ClassFactory 应该也可以.

CoCreateInstance -> CoGetClassObject -[系统|组件代码]-> DllGetClassObject -> new Component

DllGetClassObject 完全可以完成<COM 技术内幕说的> a. 灵活创建对象, b. 控制创建过程, c. IClassFactory2 , 而且这样子的实现也与语言无关
所以感觉没有必要一定要用到IClassFactory 这个接口


3.
因此在实现的时候, 完全可以这样子的实现组件
CCoClass : public IA, public IB, public IClassFactory
{
......
}

DllGetClassObject()
{
new CCoClass
}

而不需要额外的用一个类单独的去实现IClassFactory . 好像ATL 默认的就是这么干的, 提供了一个CComCoClass<CCoClass, &CLSID_CCoClass)  实现类.

这个是我的对COM IClassFactory 的理解, 感觉没必要多一个这个东西.

不知道大家是如何看待这个东西的:)


 

posted on 2007-11-18 22:53 泡泡牛 阅读(2386) 评论(4)  编辑 收藏 引用 所属分类: Develop

clip_image001

评论

# re: COM 类工厂有必要存在吗 2007-11-20 16:16 www.helpsoff.com.cn clip_image002

是觉得没必要多哪个东西呀?IClassFactory 还是一个单独实现IClassFactory 的具体类?

  回复  更多评论   

# re: COM 类工厂有必要存在吗 2007-11-20 16:21 泡泡牛 clip_image002

:/ 嘿嘿, 没说清楚

是没有必要单独实现IClassFactory 的具体类

  回复  更多评论   

# re: COM 类工厂有必要存在吗 2007-11-21 15:30 www.helpsoff.com.cn clip_image002

这个倒是事实,实不实现看个人的编程习惯了,没有强制要求的。

  回复  更多评论   

# re: COM 类工厂有必要存在吗 2007-11-21 17:07 clip_image002

在所有进程里面使用的都是一个实例.你不用IClassFactory 怎么实现.

  回复  更多评论   

 

posted on 2011-01-10 13:19 肥仔 阅读(1450) 评论(1)  编辑 收藏 引用 所属分类: COM

评论

# re: COM 类工厂有必要存在吗?  回复  更多评论   

1. ATL框架实现了一个CComClassFactory工厂类,所有自定义COM对象都是由该工厂类创建出来的。
2. CComClassFactory类的创建由DllGetClassObject->_AtlModule::DllGetClassObject创建出来
--------------------------------
为什么COM要通过两步构造的方式来创建对象,因为通过clsid创建对象只能通过查表的方式。作如下假设:
1. COM组件导出100个对象类型;
2. 游戏中要同时创建10000个某类对象;
如果每次创建对象,都是查表然后创建,那么效率非常低下。如果有了类厂,那么只需要首先取得类厂,对象的创建只是调用类厂方法10000次而已,不需要进行clsid查表了。
但是,两步创建法毕竟很繁琐,所以微软给了你一个CoCreateInstance把两步封装为一步了。这样的好处是,即提供了一步创建的接口(效率低),又提供了两步创建的接口(效率高)
2016-10-11 13:28 | 天空之城

只有注册用户登录后才能发表评论。
网站导航: 博客园   IT新闻   BlogJava   知识库   博问   管理