支持多种持久性策略的类库

时间:2008-09-22 08:37:35

标签: c++ design-patterns persistence

我正在开发一个包含域模型类的C ++类库,我想添加对从各种持久性机制(即数据库和文件)实例化这些类的支持。应该为类库的用户提供一个接口(?),用于编写可以从/向持久性机制传输数据的类。

我知道数据访问对象模式似乎适用于Java,但我不确定如何将它应用于C ++。还有其他解决方案吗?

4 个答案:

答案 0 :(得分:1)

Boost Serialization为序列化C ++类型提供了一些非常有用的东西,但是它与你想要的我不知道的界面的匹配程度如何。它支持侵入式和非侵入式设计,因此非常灵活。

答案 1 :(得分:1)

C ++支持多重继承,因此您可以拥有通用持久性API并继承持久性机制。这仍然需要使用内省来获取类元数据,但是你仍然会遇到任何持久层的问题。

或者你可以做类似的事情但是使用元数据驱动一个代码生成器,它填充持久层的'Getters'和'Setters'。

任何持久层通常都会使用一种或另一种方法,因此您的问题是将加载机制挂钩到持久层。我认为这会使您的问题与单个持久层略有不同,但是从另一个方向处理它。您不是将域类构建到持久性框架上,而是提供一组域类,其中包含持久性框架的钩子,第三方可以将其数据访问机制插入其中。

我认为,一旦提供对类元数据和回调的访问,持久性机制就相对简单了。查看任何方便的C ++ O / R映射框架的元数据组件,并了解它们的工作原理。使用API​​在域类的一个基类中封装它,并提供用于实例化或持久化的通用getter / setter API。其余部分取决于实现持久层的人。

编辑:我想不出一个C ++库,它具有你所描述的可插入持久性机制的类型,但是我在Python中做了一些可以添加这种类型设施的东西。特定的实现使用了Python中没有直接C ++等效的工具,尽管基本原理可能适用于C ++。

在Python中,您可以通过覆盖__getattr()____setattr()__来拦截对实例变量的访问。持久性机制实际上在幕后维护了自己的数据缓存。当功能混合到类中时(通过多重继承完成),它会覆盖成员访问的默认系统行为,并检查被查询的属性是否与其字典中的任何内容匹配。发生这种情况时,调用被重定向以获取或设置数据缓存中的项目。

缓存拥有自己的元数据。它了解其数据模型中的实体之间的关系,并知道要拦截哪些属性名称来访问数据。它的工作方式将其与数据库访问层分开,并且(至少在理论上)可以允许持久性机制与不同的驱动程序一起使用。没有内在的原因,你不能(例如)构建一个驱动程序将其序列化为XML文件。

在C ++中使用这样的工作会更加繁琐,并且可能无法使对象缓存访问与此系统一样透明。使用显式协议加载和刷新对象的状态到缓存可能是最好的。这个代码非常适合从缓存元数据生成,但这必须在编译时完成。您可以使用模板或覆盖->运算符来使访问协议更加透明,但这可能比它的价值更麻烦。

答案 2 :(得分:1)

我会避免序列化,恕我直言,我们在1995年为MFC中的一个应用程序实现了这个,我们足够智能使用独立对象版本控制和文件版本控制,但你最终得到了很多旧的乱码一段时间后。

想象一下某些场景,弃用类,弃用成员等,每个场景都会出现一个新问题。现在我们使用compreseds“XML类型”流,我们可以添加新数据并保持向后兼容性。

从将数据映射到对象中抽象读取和写入文件,我们现在可以切换文件格式,添加导入器/导出器而无需修改我们的核心业务对象。

有人说一些开发人员喜欢序列化,我自己的遭遇是切换代码库,平台,语言,工具包都会带来很多问题,读取和写入数据不应该是其中之一。

此外,使用标准数据格式和一些专有密钥,意味着与第三方合作更容易。

答案 3 :(得分:0)

您可能希望看一下boost serialization。没有使用它我不能说是否推荐它。 Boost库通常具有高质量。