【发布时间】:2011-09-09 12:05:26
【问题描述】:
为什么你会有一个抽象基类为只有一个(永远和永远)派生类的库定义一个接口?
【问题讨论】:
标签: c++ inheritance interface polymorphism
为什么你会有一个抽象基类为只有一个(永远和永远)派生类的库定义一个接口?
【问题讨论】:
标签: c++ inheritance interface polymorphism
您可能希望将实现换成单元测试之类的东西
【讨论】:
您这样做的一个原因是为了可测试性。当依赖对象定义为接口时,测试依赖对象要简单得多。这提供了轻松模拟或存根的能力。
【讨论】:
virtual)。
违反reused abstraction principle。
简而言之,不要这样做。
那些说“用于测试”的人忽略了你可以替换
Base < - > Derived
Base < - > DerivedForMockingAndTesting
与
Derived < - > DerivedForMockingAndTesting
也就是说,让您现有的实现 Derived 作为“抽象”,在单元测试中进行模拟和测试。
【讨论】:
Derived 的构造函数做了一些你不希望模拟做的事情怎么办?
如果您可以 100% 确定永远只有一个且完全是一个派生类?没有太多理由。但是:实际上,您几乎不会 100% 确定任何事情,当然也不是您代码的未来。
【讨论】:
您可能会发现该类的不同版本需要二进制兼容。您可能还会发现,出于其他原因,您希望封装类的定义——例如,因为定义需要一个具有不良宏的标头,诸如此类,或者包含定义类所必需的标头的标头具有编译时间很长。
例如,我编写了一个类来封装我的操作系统提供的功能 - 目前,例如动态加载和创建窗口。尽管对于一个编译目标(Windows 等)只有一个实现,但我选择使用运行时抽象,因为我想保证我的其余代码永远不会看到特定于平台的标头,并且Windows 标头充满了很多宏和东西,我不希望它们泄露出去。
【讨论】:
最明显的原因是能够把课程' 在源文件中实现,而不是在头文件中。就是这样 头文件中暴露的是抽象基类(和一个工厂函数 有必要构造它,但这可能是一个静态成员)。这 避免必须包含任何成员数据的头文件;粉刺 为此,成语在 C++ 中更为惯用,但使用抽象类,如 这远非未知,而且效果也很好。
【讨论】: