抽象基类w/o多态性

Abstract Base Class w/o Polymorphism

本文关键字:多态性 基类 抽象      更新时间:2023-10-16

为什么要让一个抽象基类为只有一个(永远)派生类的库定义接口?

您可能需要将实现换成类似单元测试的东西

这样做的一个原因是为了测试性。当依赖对象的依赖项被定义为接口时,测试它们要简单得多。这样就可以轻松地模拟或存根。

违反重用抽象原则。

简而言之,不要这样做。

那些说"为了测试"的人忽略了你可以取代

Base < - > Derived
Base < - > DerivedForMockingAndTesting

带有

Derived < - > DerivedForMockingAndTesting    

也就是说,让您现有的实现Derived作为"抽象",在单元测试中进行模拟和测试。

如果您可以100%确定始终只有一个且恰好有一个派生类?理由不多。但是:事实上,你几乎不会100%确定任何事情,当然也不会确定你的代码的未来。

您可能会发现该类的不同版本需要二进制兼容。您可能还发现,由于其他原因,您希望封装类的定义-例如,因为定义需要一个具有较差宏的标头,诸如此类的东西,或者包含定义类所需内容的标头的编译时间非常长。

例如,我编写了一个类来封装我的操作系统提供的功能——目前,比如动态加载和创建窗口。尽管一个编译目标(Windows等)只有一个实现,但我选择使用运行时抽象,因为我想保证我的代码的其余部分从未看到特定于平台的头,而且Windows头中充满了太多宏和其他东西,我不希望它们泄露出去。

最明显的原因是能够将类实现在源文件中,而不是在头中。所有这些头中公开的是抽象基类(和一个工厂函数构造它所必需的,但这可能是一个静态成员)。这避免了必须包括任何成员数据的头文件;皮条客习语在C++中更为惯用,但使用抽象类这远非未知,而且效果相当好。