为什么 leveldb 中的 table 和 tablebuilder 使用 struct rep?

bao*_*iao 5 c++ design-patterns leveldb

最近在看leveldb的源码,但是对table中的rep struct和table_builder源码很迷惑。

因为我们可以直接将成员变量直接存储在类Table和类TableBuilder中。

但是作者为什么要做一个struct Rep,并将成员变量存放在struct Rep中呢?

我可以想出一个原因,因为 table 和 table_builder 会暴露给用户,所以我们想隐藏实现。这样对吗?或者还有其他一些我想念的想法,或者是某种设计模式?

谢谢

Dan*_*rul 5

这是从 中提取的代码片段,来自table.h的代码片段table_builder.h将显示类似的设计

class Table 
{
    ...
    struct Rep;
    Rep* rep_;
    ...
};
Run Code Online (Sandbox Code Playgroud)

因此,您提出的解释是正确的:

  • 类的声明table.htable_builder.h暴露给leveldb客户;
  • 然而,设计者不想暴露数据的内部表示,因为它们是实现细节并且在接口中是不必要的;
  • 因此,这些细节已移出到一个单独的结构中,该结构Rep在公共接口(头文件)中声明,但仅在实现文件(源文件)中定义和使用;
  • 这是一个相当常见的习语,通常称为pImpl 习语(因为指向实现的指针通常称为pImpl)或编译防火墙

除了设计封装,这个习语还有另一个原因,那就是可用性。实际上,如果 的内部详细信息在Table中公开Table.h,则Table.h每次更改这些详细信息时都必须重新编译包含的任何 leveldb 用户的源文件。

通过隐藏这些实现细节,leveldb 用户的源文件不受 leveldb 数据内部表示更改的影响。只要 leveldb 公共接口(公共头文件)不改变,用户就可以从一个版本的 leveldb 升级到另一个版本,而无需重新编译他们的源代码:他们只需要链接到新版本的 leveldb 库。

因此,这个习惯用法对于库开发人员来说极其重要,并且也可以用于最小化程序不同模块之间的耦合。