- 1、原创力文档(book118)网站文档一经付费(服务费),不意味着购买了该文档的版权,仅供个人/单位学习、研究之用,不得用于商业用途,未经授权,严禁复制、发行、汇编、翻译或者网络传播等,侵权必究。。
- 2、本站所有内容均由合作方或网友上传,本站不对文档的完整性、权威性及其观点立场正确性做任何保证或承诺!文档内容仅供研究参考,付费前请自行鉴别。如您付费,意味着您自己接受本站规则且自行承担风险,本站不退款、不进行额外附加服务;查看《如何避免下载的几个坑》。如果您已付费下载过本站文档,您可以点击 这里二次下载。
- 3、如文档侵犯商业秘密、侵犯著作权、侵犯人身权等,请点击“版权申诉”(推荐),也可以打举报电话:400-050-0827(电话支持时间:9:00-18:30)。
- 4、该文档为VIP文档,如果想要下载,成为VIP会员后,下载免费。
- 5、成为VIP后,下载本文档将扣除1次下载权益。下载后,不支持退款、换文档。如有疑问请联系我们。
- 6、成为VIP后,您将拥有八大权益,权益包括:VIP文档下载权益、阅读免打扰、文档格式转换、高级专利检索、专属身份标志、高级客服、多端互通、版权登记。
- 7、VIP文档为合作方或网友上传,每下载1次, 网站将根据用户上传文档的质量评分、类型等,对文档贡献者给予高额补贴、流量扶持。如果你也想贡献VIP文档。上传文档
查看更多
外部的多态一种用于透明地扩展c具体数据类型的对象结构模式
外部的多态:一种用于透明地扩展c++具体数据类型的对象结构模式
(作者:Chris Cleeland,Douglas C. Schmidt ,by huihoo.org CORBA课题 Thzhang 译 , Allen整理,制作)
意图
允许那些没有继承关系或/和没有虚函数的类能够被多态地对待。这些没有关系的类能够被使用它们的软件以一种共同的行为处理。
动机
使用来自不同源的C++类是非常困难的。一个应用经常希望这些类能够投射(project)到一个共同的行为,但是却受到这些类存在设计的限制。如果仅仅是类的接口需要适配,一个明显解决方法是使用对象结构模式,如适配器和装饰。有时候却要有更复杂的需求,如需要改变底层的接口和实现。在这种情况下,这些类可能被需要表现得好像它们拥有一个共同的祖先(父类)。 例如,考虑这样一个情况,我们正在调试一个由来自于不同c++库的类构成的应用。如果能够要求任意类实例以人可读的形式将其内部状态导出到文件或是控制台显示将是非常便捷的。如果能够将所有活动的类实例收集到集合中,使用迭代器遍历集合中的每个实例,要求它们导出自己的状态就更加方便。 因为集合是同质的(译者:即要求其中所有的对象是相同类型的),为了维护一个单一的集合,一个共同的基类必须存在。应为目前的类是已经被设计好的、实现好的并且被使用中的,通过修改继承树来引入公共的基类不是一个选择,我们可能不能访问到类的源代码。此外,类在像C++这种OO语言是具体的数据类型,这就要求有严格的存储布局,但这个布局是受到隐藏指针(如C++中的虚表指针)制约的。用一个共同的、多态的基类来重新实现这些类是不现实的。 于是,将无关的类投射到一个共同的行为需要确定以下约束该解决方案的各种因素: 1、空间效率。解决方案不能限制已经存在对象的存储布局。特别是哪些没有虚函数的类,一定不要迫使它们增加虚表指针。 2、多态。所有库对象必须以一个统一、透明的行为来访问。特别是那些新包含在系统中的类,我们不希望改变存在的代码。 考虑下面使用来自于ACE编程框架类的例子: 1. SOCK_Acceptor acceptor; // Global storage 2. 3. int main (void) { 4. SOCK_Stream stream; // Automatic storage 5. INET_Addr *addr = 6. new INET_Addr // Dynamic storage. 7. ... SOCK_Stream、SOCK_Acceptor和INET_Addr类都是具体的数据类型,因为它们没有继承自共同的祖先和/或它们不包含虚函数。如果在一个调试会话中,一个应用希望检测所有活动的ACE对象的状态,我们可能得到下面的输出: Sock_Stream::this = 0x47c393ab, handle_ = {-1} SOCK_Acceptor::this = 0x2c49a45b, handle_ = {-1} INET_Addr::this = 0x3c48a432, port_ = {0}, addr_ = {0.0.0.0} 在不改变其二进制布局情况下,通过投射来导出这些类实例状态的一种有效的方法是使用外部多态模式。这个模式构建了一种平行的、外部继承的层次,它使一个不必有继承关系的具体类集合投射到一个多态的行为上。下面的OMT图展示了如何使用外部多态模式来创建一个外部的,并行的类层次:
像图示中展示的那样,我们定义了一个抽象类dumpable,其拥有希望的dump接口方法。参数化类ConcreteDumpable从抽象类dumpable继承同时拥有一个指向参数类实例的指针,就是SOCK_Stream.。此外,它还为dump接口定义了一个实现(body),这个实现委托模板函数dump来完成最终的功能。dump模板函数将调用具体的实现类的对应方法,也就是SOCK_Stream::dump或INET_Addr::printTo。 使用外部多态模式,现在就可以实现收集dumpable实例,并通过迭代器遍历它们,以一致行为调用每个实例中的dump方法。注意的是原始的ACE具体数据类型没有被改变。
适应性
在下列情况下使用外部多态模式: 1、你的类库包含并不是从一个拥有虚方法的公共基类继承的具体数据类型。 2、你的类库或应用的行为可以被显著的简化,如果你能够以一种多态的行为看待所有的对象。 在下列情况下不要使用外部多态模式: 1、你的类库已经包含了从拥有虚方法的公共基类继承的抽象的数据类型。 2、你的编程语言和环境允许类动态的增加方法。
结构和参与者
1、Common (Dumpable
文档评论(0)