我已经在网上搜索了有关如何在C ++课程中有效设计持久性模型的具体设计信息,并且我已经做得很短。所以我决定在这里问一下。
我们说我有4节课:
A类
B类
C类
Class Persist
我希望使用类#34; Persist"将类A,B和C保存到磁盘。这样一个文件包含每个类的配置信息:
my_module.json
{
A {
...
},
B {
...
},
C {
...
}
}
我的问题是,设计这种方法的最佳方法是遵循SOLID原则吗?
例如,单一责任原则表明,一个班级应该只有一个责任(或只有一个改变的理由),而得墨忒耳法则建议班级尽可能少知道。
那么:
1)一个班级应该知道如何序列化自己,还是已经违反了单一责任?
2)如果我使用第三方图书馆,例如"麦片"要序列化" A类",我需要在" A类"的内部成员中添加标签。向引擎显示它应该如何序列化。这增加了" A类和#34;之间的耦合。和第三方引擎,这一定是坏的吗?
3)我应该使用中间类来转换对象来自" A类和#34;进入具有第三方库可以理解的适当标签的对象?这消除了来自" A类和#34;的任何序列化知识,但它增加了更多的复杂性和更多的类。
4)班级应该知道持久性模块吗?尝试序列化时这是否现实?如果是这样,该类应如何通知持久性模块状态已更改并且是否有时间持续存在?或者持久性模块是否应该定期轮询对象以进行全新配置?
我对OO相当新,但对此非常感兴趣。关于类之间交互的细节将非常有用。感谢。
答案 0 :(得分:0)
通常在软件工程中,决策不是关于原则,而是关于权衡。
1 - 它违反了单一责任,但在C ++中你没有太多选择。该语言本身不支持运行时反射,也不支持虚拟构造函数/类工厂。如果没有这两个特性,在没有对象序列化的情况下实现对象序列化是非常困难的。 “非常努力”我的意思是它需要外部工具,或许多宏/模板,IMO非常昂贵,以支持长期。
2 - 它增加了耦合,增加了很多复杂性(你必须支持你正在使用的任何第三方库),但如果你需要同时支持多种不同的序列化格式,例如无论是JSON,XML还是二进制文件,它都可能是一件好事。
3 - 取决于但我会说“不”。中间表示的良好格式是DOM树状的,你会浪费太多的CPU时间来构建,因为太多的小RAM分配和指针追逐。如果由于某种原因你想要设计和支持明确定义的中间表示,我将它构建为一对事件驱动的接口(一个读者另一个作者),请参阅SAX获取灵感。
4 - 大多数序列化库的设计使得保存/加载是一次性过程。原因是大多数现代通用序列化格式(XML,JSON,大多数二进制格式)不支持更新。无论如何,你必须写出一个完整的文件。通知仅在存储格式支持部分更新时才带来价值,例如:如果您正在[嵌入]数据库中保存/加载,而不仅仅是在JSON文件中。通常的做法是,每次完成对象的修改后,从外部手动调用save。通过自动保存,很容易浪费过多的IO带宽和CPU时间,在一些不一致的中间状态下写入对象。