我正在开发一个包含域模型类的 C++ 类库,并且我想添加对从各种持久性机制(即数据库和文件)实例化这些类的支持。应该给类库的用户一个接口(?)来编写一个可以从/向持久性机制传输数据的类。
我知道似乎适用于 Java 的数据访问对象模式,但我不确定如何将其应用于 C++。还有其他解决方案吗?
我正在开发一个包含域模型类的 C++ 类库,并且我想添加对从各种持久性机制(即数据库和文件)实例化这些类的支持。应该给类库的用户一个接口(?)来编写一个可以从/向持久性机制传输数据的类。
我知道似乎适用于 Java 的数据访问对象模式,但我不确定如何将其应用于 C++。还有其他解决方案吗?
Boost Serialization为处理 C++ 类型的序列化提供了一些非常有用的东西,但它与你想要的接口的匹配程度我不知道。它支持侵入式和非侵入式设计,因此非常灵活。
C++ 支持多重继承,因此您可以拥有通用的持久性 API 并继承持久性机制。这仍然需要使用自省来获取类元数据,但是对于任何持久层,您仍然会遇到这个问题。
或者,您可以执行类似的操作,但使用元数据驱动代码生成器,该代码生成器为持久层填充“Getters”和“Setters”。
任何持久层通常会使用一种或另一种方法,因此您的问题是将加载机制挂钩到持久层。我认为这使您的问题与单个持久层没有什么不同,而是从另一个方向解决它。您不是在持久性框架上构建域类,而是提供一组域类,其中包含第三方可以插入其数据访问机制的持久性框架的钩子。
我认为一旦您提供对类元数据和回调的访问权限,持久性机制就相对简单。查看任何方便的 C++ O/R 映射框架的元数据组件并了解它们是如何工作的。使用 API 将其封装在您的域类的基类之一中,并提供通用的 getter/setter API 用于实例化或持久化。其余的取决于实现持久层的人。
编辑: 我想不出具有您所描述的可插入持久性机制类型的 C++ 库,但我在 Python 中做了一些可以添加这种类型的工具的事情。特定的实现使用 Python 中的工具,没有直接的 C++ 等价物,尽管基本原理可能适用于 C++。
在 Python 中,您可以通过覆盖__getattr()__
和来拦截对实例变量的访问__setattr()__
。持久化机制实际上在幕后维护了自己的数据缓存。当功能被混合到类中(通过多重继承完成)时,它会覆盖默认的系统行为来访问成员并检查被查询的属性是否匹配其字典中的任何内容。发生这种情况时,调用被重定向以获取或设置数据缓存中的项目。
缓存有自己的元数据。它知道其数据模型中实体之间的关系,并且知道要拦截哪些属性名称来访问数据。这种工作方式将其与数据库访问层分开,并且可以(至少在理论上)允许持久性机制与不同的驱动程序一起使用。您不能(例如)构建一个将其序列化为 XML 文件的驱动程序并没有内在的原因。
在 C++ 中进行类似的工作会有点繁琐,并且可能无法使对象缓存访问像在该系统中那样透明。您可能最好使用一个显式协议,该协议将对象的状态加载并刷新到缓存中。从缓存元数据生成的代码非常适合,但这必须在编译时完成。您可以使用模板或通过覆盖->
操作符来使访问协议更加透明来做一些事情,但这可能比它的价值更麻烦。
我会避免序列化,恕我直言,我们早在 1995 年就在 MFC 中为我们的一个应用程序实现了这个,我们足够聪明,可以使用独立的对象版本控制和文件版本控制,但你最终会得到很多旧的混乱代码。
想象某些场景,弃用类、弃用成员等,每一个都提出了一个新问题。现在我们使用压缩的“XML 类型”流,我们可以添加新数据并保持向后兼容性。
读取和写入文件是从将数据映射到对象中抽象出来的,我们现在可以切换文件格式,添加导入器/导出器而无需修改我们的核心业务对象。
话虽如此,有些开发者喜欢序列化,但我自己的遭遇是,切换代码库、平台、语言、工具包都会带来很多问题,读取和写入数据不应该是其中之一。
此外,使用带有一些专有密钥的标准数据格式,意味着它更容易与第三方合作。
您可能想查看boost serialization。没用过,不知道推荐不推荐。Boost 库通常是高质量的。