-
-
[讨论]我不喜欢QueryInterface
-
发表于:
2011-3-5 18:05
5873
-
我不喜欢QueryInterface
COM中提供了一个最基础的类 IUnknown。这个类实际上包含了两个内容,一个是计数器,包括 AddRef() 和 Release()。这是个好东西,结合智能指针 CComPtr ,即使我们不用 COM ,善用这套计数器系统,应用于我们的C++代码,也是一件好事。
IUnknown的另一个内容,是 QueryInterface 。我认为,这不是什么好东西,要谨慎使用。这里详细讨论它。
我理解,QueryInterface的好处,是让接口之间的关系变得松散一点。使用一个函数,就可以得到任何你想要的接口。即使这个接口并没有被实现,也不会崩溃。理解了它存在的意义,我们就不会滥用它了。
首先,QueryInterface应该处在接口与接口之间。什么地方才需要有接口呢?是模块与模块之间。一个模块提供了一些服务,另一个模块需要使用这些服务,就可以用接口来建立联系。接口的设计要谨慎,要简练。应该封装在一个模块内部的内部,绝不在接口中出现,不让另一个模块知道。所以,在一个模块内部,同一个project的不同cpp文件之间,并不需要用接口,并不需要用QueryInterface。
第二个问题。因为 QueryInterface 太自由了,你可以希望从一个接口中得到任何其它接口。但“任何”这个词,太自由了。我究竟可以期望得到什么呢?我总是去 QueryInterface 一个它永不可能实现的接口,并没有什么意义。所以,我推荐,当我们写一个接口时,最好注明,从本接口,你可以期望获得什么接口,在注解中,把所有有可能会获取成功的接口列出来。这样使用这个接口的人才知道怎么用。完成这个接口的人才知道需要考虑哪些情况。
第三个问题。还是这个 QueryInterface 太自由了。你可以从接口A得到接口B,也可以从接口B得到接口A。但我想这样并不好。我建议,把 QueryInterface 理解了得到子接口。如果从A得到B,那么B是A的子接口。尽量不要让B再可以得到A。用树状的立体构架,不要用平面构架,所有的接口都站同一个高度,都可以互相得到,就乱套了。
第四个问题。很多人喜欢用 return this 来实现 QueryInterface。并且总是这样实现。这样就没有子接口的概念了,就陷入上一个问题了。我认为,你可以偶尔地用 return this 来实现 QueryInterface,但要理解并不总是这样的。尤其是上层调用接口的人,更不能假设接口A得到了接口B,这个A与B其实是一样的,就一定可以互相得到的。
第五点,接口不要滥用。每一个接口,都应该在树状结构的接口定义中,占有自己不可替代的作用。每一个接口,都应该有密切相关的一组方法,一起完成特定的工作。如果你定义了很多接口,每个接口都只有一个方法,那么很可能你错了。我有一个程序员,操作一个文件,得到A,里面只有一个方法是open;再得到接口B,里面只有一个方法是read;再得到接口C,里面只有一个方法是close。这是不好的。
苏州WinMount继续招程序员,简历请发到 support@winmount.com
[课程]Android-CTF解题方法汇总!