为C+;中的许多类设计持久性模型的最佳方法是什么+;同时也要确保遵循坚实的原则? 我在Web上搜索了一些关于如何在C++类中有效设计持久性模型的特定设计信息,我已经很短了。所以我决定在这里问

为C+;中的许多类设计持久性模型的最佳方法是什么+;同时也要确保遵循坚实的原则? 我在Web上搜索了一些关于如何在C++类中有效设计持久性模型的特定设计信息,我已经很短了。所以我决定在这里问,c++,persistence,solid-principles,C++,Persistence,Solid Principles,假设我有4门课: 甲级 B类 C类 阶级坚持 我想使用类“persist”将类A、B和C持久化到磁盘,以便一个文件包含每个类的配置信息: my_module.json { A { ... }, B { ... }, C { ... } } 我的问题是,最好的设计方法是什么,这样才能遵循坚实的原则 例如,单一责任原则建议一个类应该只有一个责任(或者只有一个改变的理由),而德米特定律则建议各类之间尽可能少地相互了解 那么: 1) 类应该知道如何序列化

假设我有4门课:

甲级

B类

C类

阶级坚持

我想使用类“persist”将类A、B和C持久化到磁盘,以便一个文件包含每个类的配置信息:

my_module.json
{
  A {
    ...
  },
  B {
    ...
  },
  C {
    ...
  }
}
我的问题是,最好的设计方法是什么,这样才能遵循坚实的原则

例如,单一责任原则建议一个类应该只有一个责任(或者只有一个改变的理由),而德米特定律则建议各类之间尽可能少地相互了解

那么:

1) 类应该知道如何序列化自己,还是已经违反了单一责任

2) 如果我使用第三方库(如“grane”)序列化“Class a”,我将需要向“Class a”的内部成员添加标记,以向引擎展示它应该如何序列化。这增加了“A级”和第三方引擎之间的耦合,这一定很糟糕吧

3) 我是否应该使用中间类将对象从“Class A”转换为具有第三方库可以理解的适当标记的对象?这从“类A”中删除了任何序列化知识,但它增加了更多的复杂性和类

4) 类是否应该知道持久性模块?在尝试序列化时,这是否现实?如果是这样的话,类应该如何通知持久化模块状态已经改变,是时候持久化了?或者,持久化模块是否应该定期轮询对象以获得新的配置


我是OO的新手,但对OO非常感兴趣。关于类之间交互的细节将非常有用。谢谢。

通常在软件工程中,决策与原则无关,而是权衡

1——它违反了单一的责任,但是C++中你没有太多选择。该语言本身不支持运行时反射,也不支持虚拟构造函数/类工厂。如果没有这两个特性,如果对象本身没有序列化,就很难实现对象序列化。我所说的“非常难”是指它需要外部工具,或大量宏/模板,我认为长期支持非常昂贵

2-它增加了耦合,增加了很多复杂性(您必须支持正在使用的任何第三方库),但是如果您需要同时支持多种不同的序列化格式,例如JSON、XML和二进制,这仍然是一件好事

3-视情况而定,但我会说“不”。中间表示的好格式是类似于DOM树的格式,构建这种格式会浪费太多CPU时间,因为太多的小RAM分配和指针跟踪。如果出于某种原因,您希望设计和支持定义良好的中间表示,我将其结构化为一对事件驱动接口(一个读者,另一个作者),请参阅以获取灵感


4-大多数序列化库的设计使保存/加载是一次性过程。原因是大多数现代通用序列化格式(XML、JSON、大多数二进制格式)不支持更新。无论如何,你必须写出一份完整的文件。仅当存储格式支持部分更新时,通知才有价值,例如,如果您正在[嵌入式]数据库中保存/加载,而不仅仅是在JSON文件中。通常的做法是,每次修改完对象后,从外部手动调用save。使用自动保存,在某些不一致的中间状态下写入对象很容易浪费太多的IO带宽和CPU时间。

对于学术界以外的任何事情,都应该对原则持保留态度。它们是原则,因为如果你不遵循它们,你将面临某些缺点。然而,这并不像好与坏那么简单。例如,2)如果您决定使用Groove,那么向类添加注释并没有什么不好的,您只需要知道,一旦您这样做,您就无法轻松切换到其他seriazataion框架(或者一些工作丢失),这可能是一个主要问题,或者可能还可以。。。顺便说一句,这个问题太宽泛了,非常感谢你的回答。对于#4,不幸的是对于我的情况,保存和加载也需要定期进行。您介意详细说明类如何通知串行引擎它已完成修改对象吗?我想它必须知道串行引擎,才能通知它对象修改已经完成,正确吗?通常有没有更好的方法将序列化引擎与需要序列化的类解耦?