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

why table and tablebuilder in leveldb use struct rep?

最近看了leveldb的源码,但是对table和table_builder源码中的rep结构体感到困惑

因为我们可以直接在classTable和classTableBuilder中直接存储成员变量。

但是为什么作者做了一个struct Rep,把成员变量存放在struct Rep中

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

谢谢

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

class Table 
{
    ...
    struct Rep;
    Rep* rep_;
    ...
};

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

  • table.htable_builder.h 的声明暴露给 leveldb 客户;
  • 但是,设计者不想公开数据的内部表示,因为它们是实现细节,在接口中是不必要的;
  • 因此,这些细节已被移出到一个单独的结构中,该结构 Rep 在 public 接口(头文件)中声明,但仅在实现文件中定义和使用(源文件);
  • 这是一个相当常见的成语,通常称为 pImpl idiom (since the pointer to the implementation often is called pImpl) or a compilation firewall

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

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

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