乌托邦式接口和实现分离技术
定义方式,太难看了。让世界稍微美好一点吧!于是我们提供一个辅助类:
<!--[if !supportEmptyParas]--> template<typename T>struct Empty{};
现在,我们可以这样定义ConcreteClassN了: Typedef Reform<InterfaceN, ImpInterface0, ImpInterface1,
是不是清爽了很多? 在继续下面内容以前,请回味一下这个不是问题的问题: 假设IReader有3种实现,IRefCount有3种实现,我们将如何漂亮地解决掉他们。 <!--[endif]--> 现实世界总是要复杂得多,让我们进入真实的世界。回顾这个接口: struct IRWiter : IReader, IWriter;
假设我们确实需要IReader, IWriter,但是并不需要IRWrite,可不可以让一个对象同时支持这两个接口呢,就像COM一样?当然可以,我们借助于这样一个辅助模版: template<typename B1, typename B2>
为了现实需要,我们可以提供Combine的多个特化版本以支持任意数量的接口组合。如果仅仅是为了去掉一个IRWiter就引入一个Combine,虽有好处,但是意义也不大。那么,考虑这样一个例子。 struct IHttpReader : IReader;
我们需要一个对象,同时支持从网络和从文件读取的能力。先看不引入Combine的做法: struct IFileHttpReader : IFileReader , IHttpReader; 觉得有什么问题吗?ImpReader同时实现了IFileReader分支和IHttpReader分支中的IReader,但是,和IRefCount不同的是,我们完全有理由相信,这两个分支其实需要不同的IReader的实现。即使IReader确实可以是同样的实现,另一个严重的问题是,ImpReader是一个不完整的实现,ImpFileReader和ImpHttpReader都分别重载了IReader中的一部分方法,例如,两者都实现了如下方法: virtual bool open(const char* url);
如何解决这个问题?让我们回顾一下IFileHttpReader,首先这个接口就是个问题产物: open到底open什么?文件,还是HTTP连接,还是两个都打开?也就是说,从概念上来讲,IFileHttpReader就存在矛盾,这样的概念很显然是难以维护的。其次,我们完全没有办法为两个分支提供不同的实现,当然,其根源是IFileHttpReader的错误设计导致的,不采用我们这里提到的技术,问题依然存在。现在引入一个结论:如果某个接口的基类树中多次出现同一个接口,我们的技术无法为这些接口分别提供不同的实现。这里的解决方案是抛弃IFileHttpReader,引入Combine, 我们可以这样解决问题: typedef Reform<
假设,ImpReader不能同时满足两个分支的要求,我们 |
凌众科技专业提供服务器租用、服务器托管、企业邮局、虚拟主机等服务,公司网站:http://www.lingzhong.cn 为了给广大客户了解更多的技术信息,本技术文章收集来源于网络,凌众科技尊重文章作者的版权,如果有涉及你的版权有必要删除你的文章,请和我们联系。以上信息与文章正文是不可分割的一部分,如果您要转载本文章,请保留以上信息,谢谢! |