快速业务通道

乌托邦式接口和实现分离技术

作者 佚名技术 来源 程序设计 浏览 发布时间 2012-06-30
定义方式,太难看了。让世界稍微美好一点吧!于是我们提供一个辅助类:

<!--[if !supportEmptyParas]--> template<typename T>struct Empty{};
template<typename I, typename template<class> class B>
struct Merge{ <!--[if !supportEmptyParas]-->typedef B<I> type;};
template<typename I >
struct Merge<I, Empty >{
typedef I type;
<!--[if !supportEmptyParas]--> }; <!--[endif]-->
template

typename I,
typename template<class> class B1,
typename template<class> class B2 = Empty,

typename template<class> class Bn = Empty,

struct Reform{
typedef typename Merge<
typename Merge<
typename Merge<I, B1>::type
, B2>::type , …,Bn>::type type;
};

现在,我们可以这样定义ConcreteClassN了:

Typedef Reform<InterfaceN, ImpInterface0, ImpInterface1,
…ImpInterfaceN>::type ConcreteClassN;

是不是清爽了很多?

在继续下面内容以前,请回味一下这个不是问题的问题:

假设IReader有3种实现,IRefCount有3种实现,我们将如何漂亮地解决掉他们。 <!--[endif]-->

现实世界总是要复杂得多,让我们进入真实的世界。回顾这个接口:

struct IRWiter : IReader, IWriter;

假设我们确实需要IReader, IWriter,但是并不需要IRWrite,可不可以让一个对象同时支持这两个接口呢,就像COM一样?当然可以,我们借助于这样一个辅助模版:

template<typename B1, typename B2>
struct Combine : B1, B2{
typedef B1 type1;
typedef B1 type2;
<!--[if !supportEmptyParas]--> }; <!--[endif]-->
typedef Reform< Combine<IReader, IWriter>, ImpRefCount, ImpWriter, ImpReader >::type ConcreteRWiter

为了现实需要,我们可以提供Combine的多个特化版本以支持任意数量的接口组合。如果仅仅是为了去掉一个IRWiter就引入一个Combine,虽有好处,但是意义也不大。那么,考虑这样一个例子。

struct IHttpReader : IReader;
struct IFileReader : IReader;

我们需要一个对象,同时支持从网络和从文件读取的能力。先看不引入Combine的做法:

struct IFileHttpReader : IFileReader , IHttpReader;
typedef Reform<IFileHttpReader, ImpRefCount, ImpHttpReader,
ImpFileReader>::type ConcreteRWiter;

觉得有什么问题吗?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<
Combine< ImpFileReader <IFileReader>, ImpHttpReader <IHttpReader> >,
ImpRefCount, ImpReader
>::type ConcreteFileHttpReader;

假设,ImpReader不能同时满足两个分支的要求,我们

凌众科技专业提供服务器租用、服务器托管、企业邮局、虚拟主机等服务,公司网站:http://www.lingzhong.cn 为了给广大客户了解更多的技术信息,本技术文章收集来源于网络,凌众科技尊重文章作者的版权,如果有涉及你的版权有必要删除你的文章,请和我们联系。以上信息与文章正文是不可分割的一部分,如果您要转载本文章,请保留以上信息,谢谢!

分享到: 更多

Copyright ©1999-2011 厦门凌众科技有限公司 厦门优通互联科技开发有限公司 All rights reserved

地址(ADD):厦门软件园二期望海路63号701E(东南融通旁) 邮编(ZIP):361008

电话:0592-5908028 传真:0592-5908039 咨询信箱:web@lingzhong.cn 咨询OICQ:173723134

《中华人民共和国增值电信业务经营许可证》闽B2-20100024  ICP备案:闽ICP备05037997号