包装器设计模式

Wrapper design pattern

提问人:Luchian Grigore 提问时间:8/5/2011 最后编辑:Luchian Grigore 更新时间:7/15/2015 访问量:1286

问:

假设我有一个班级:

class B;
class A{
public:
    A();
    virtual B foo();
}

在第三方组件中定义。我想包装类 A 和 B,结果为 myA 和 myB。 现在,我应该无法从外部访问 A 类和 B 类,而是对 myA 和 myB 具有相同的功能。foo() 可以从第三方模块调用。

我更愿意使用继承而不是封装来做到这一点。

所以有2个问题:

  1. 如果 a 的类型为 myA,则调用 a->myFoo()(由于签名相同且返回类型不同而需要重命名方法)应调用 A::foo()。
  2. 如果 a 的类型类为 myA2::myA,则调用 a->myFoo() 应调用 myA2::myFoo()。

关于如何优雅地做到这一点的任何建议?我想出了一些解决方案,但我更喜欢对整个事情有新的看法。

编辑:

只是一个理论问题。我实际上不需要这样做,只是想办法实现它。

编辑2:

myA2 是扩展 myA 的类。在该模式之前,它被称为 A2(从第三方模块扩展类 A 的类)。

C++ 设计模式

评论

3赞 antlersoft 8/5/2011
尽管您声明了偏好,但您应该为此使用封装,而不是继承。通过封装,可以隔离第三方库上的所有依赖项。
1赞 Nawaz 8/5/2011
Luchian:包裹和包裹,但是什么?myAAmyBBmyA2
0赞 Luchian Grigore 8/5/2011
myA2 扩展了 myA。查看第二次编辑。
0赞 APC 8/5/2011
我讨厌理论问题。如果您有一个特定的用例,需要您考虑选择当前最佳实践以外的任何内容,请向我们提供详细信息。否则,请在此类问题所属 programmers.stackexchange.com 上提问。谢谢

答:

2赞 Ryan Ballantyne 8/5/2011 #1

我不明白为什么你更喜欢用继承而不是封装来做这件事。一般来说,扩展要包装的类是实现包装器模式的“错误”方式,特别是因为您通常希望在此过程中重新定义接口。在类 myA 中,您将有一个 A 类型的字段,其中包含类 A 的实例,myA 中的方法可以根据需要调用该实例。除非我误解了你想完成的事情,否则这是完成你想要的事情的最优雅的方式。

评论

0赞 Luchian Grigore 8/5/2011
我知道,但我正在寻找没有封装的最优雅的方式。纯粹理论上的...
1赞 Mark B 8/5/2011
@Luchian Grigore:你为什么要故意让自己远离最好的方法,即使是一个理论问题?
0赞 Ryan Ballantyne 8/5/2011
所以你只是在探索实现包装器模式的方法,这显然比组合更糟糕?嗯,好吧。
0赞 Luchian Grigore 8/5/2011
我们所知道的最佳方法。:P
0赞 John Humphreys 8/5/2011 #2

您应该能够以类似的方式声明函数名称/参数。查看: strange-inheritance section: [23.9] 是什么意思, Warning: hides ?在第 3 个代码块上。Derived::f(char)Base::f(double)

它还显示了调用基方法的语法。

评论

1赞 Luchian Grigore 8/5/2011
这不适用。在这种情况下,参数会有所不同。就我而言,返回类型不同。编译器将抛出错误,而不是警告。
0赞 John Humphreys 8/5/2011
再往前看,第三个代码块重新定义了相同的参数/函数名称,并使用基本语法来调用函数的基本版本。所以它就像你问的那样隐藏在界面后面。