为什么 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.h
和 table_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 库。
因此,这个习惯用法对于库开发人员来说极其重要,也可以用来最小化程序不同模块之间的耦合。
最近看了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.h
和table_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 库。
因此,这个习惯用法对于库开发人员来说极其重要,也可以用来最小化程序不同模块之间的耦合。