目前正在寻找一个好的OO设计来序列化C ++ / Qt应用程序 想象一下,应用程序的类是基于树结构组织的,使用Composite-Pattern实现,如下图所示。
我想到的两个可能的原则:
1.)
将save()/ load()函数放在每个必须可序列化的类中。
如果已经多次看过,通常用boost来实现。
在课堂的某个地方你会发现这样的事情:
friend class boost::serialization::access;
template<class Archive>
void serialize(Archive & ar, const unsigned int version)
{
ar & m_meber1;
}
您也可以将其分为save()和load()。
但这种方法的缺点是:
如果你想在两个月之后改变序列化(对于XML,HTML或者非常好奇的东西,这会增加不支持),你必须采用所有数千个类。
在我看来,这不是一个好的OO设计
如果你想同时支持不同的序列化(XML,二进制,ASCII,等等......),那么只有80%的cpp存在于序列化函数中。
2。)
我知道boost还提供了序列化的非侵入式版本
“http://www.boost.org/doc/libs/1_49_0/libs/serialization/doc/tutorial.html”
另一种方法是实现迭代复合树结构并序列化每个对象的Iterator(以及用于反序列化的一个迭代器)
(我认为这是.NET-Framework的XmlSerializer-Class所做的,但我不熟悉.NET)
这听起来更好,因为单独的save()和load()以及序列化更改时只有一个点可以改变
所以这听起来更好,但是:
- 你必须为你要序列化的每个参数提供一个setter()和一个getter()。 (所以,不再有私人数据。(这好/坏吗?))
- 你可以在复合树上挂一个长继承hirarchy(超过5个类)
那么如何调用派生类的setter()/ getter()?
当你只能调用基础Composite-Component的接口函数时。
另一种方法是将对象数据序列化为单独的抽象格式。 从中可以获得所有可能的后续序列化(XML,TEXT,无论可能)以获取其数据。 一个想法是将其序列化为QDomNode。 但我认为额外的抽象会降低性能。
所以我的问题是:
有没有人知道一个好的OO-Design进行序列化?
也许来自其他编程语言,如JAVA,Python,C#,等等......
谢谢。
答案 0 :(得分:2)
小心序列化。
序列化是关于拍摄内存中表示的快照并稍后恢复它。
这一切都很棒,只是当你考虑使用较新版本的软件(向后兼容性)或(上帝禁止)加载以前存储的快照时,它会开始磨损接缝使用较旧版本的软件存储快照(向前兼容性)。
许多结构可以轻松处理向后兼容性,但是向前兼容性要求您的新格式非常接近其先前的迭代:基本上,只需添加/删除一些字段但保持相同的整体结构。
问题在于,出于性能原因,序列化往往会将磁盘上的结构与内存中的表示联系起来;更改内存中表示然后需要弃用旧存档(和/或迁移实用程序)。
另一方面,消息传递系统(这就是google protobuf)是关于将交换的消息结构与内存中表示分离,以便您的应用程序保持灵活性。
因此,您首先需要选择是否实施序列化或消息。
现在你可以在课堂内或课堂外编写保存/加载代码。这又是一次权衡:
请注意,隐藏状态没有任何缺点。 class
没有(真正)隐藏状态:
mutable
值)就是这样,它们可以毫无顾虑地丢失FILE*
或其他句柄)通常可通过其他方式恢复(例如序列化文件名)我个人使用两者兼而有之。
v1
中使用快速(反)序列化。编写新代码以与v1
和v2
一起使用,默认情况下在v1
中写入,直到先前版本消失为止;然后切换到写v2
(假设这很容易)。偶尔,大规模的重构会使向后兼容性太痛苦,我们此时将其丢弃在地板上(并增加主要数字)。注意:我正在处理服务器应用程序,因此我的建议反映了这种环境的细节。我想客户端应用程序必须永远支持旧版本......