C++ “设计模式”;“保存”;

C++ “设计模式”;“保存”;,c++,xml,qt,design-patterns,save,C++,Xml,Qt,Design Patterns,Save,我目前正在研究一种“保存”机制,它允许用户将他正在处理的项目保存在硬盘上。输出将是一个包含各种数据的XML文件。 现在我们的项目结构即将改变,我们需要编写一个新的xml文件(创建一个新的保存方法)。 现在面临的挑战是:保存时,我希望用户能够选择要创建的文件格式(版本1(旧)或版本2(新))。 现在有人知道如何做到这一点吗?有合适的设计模式吗? 评论: -我们正在保存的数据可以被视为不相关的块,因此用新块交换旧块实际上很容易。 -它的全部目标是,当加载一个旧项目时,它应该是可读的。(我假设这可以通

我目前正在研究一种“保存”机制,它允许用户将他正在处理的项目保存在硬盘上。输出将是一个包含各种数据的XML文件。
现在我们的项目结构即将改变,我们需要编写一个新的xml文件(创建一个新的保存方法)。
现在面临的挑战是:保存时,我希望用户能够选择要创建的文件格式(版本1(旧)或版本2(新))。
现在有人知道如何做到这一点吗?有合适的设计模式吗?
评论: -我们正在保存的数据可以被视为不相关的块,因此用新块交换旧块实际上很容易。
-它的全部目标是,当加载一个旧项目时,它应该是可读的。(我假设这可以通过标签来完成,加载时只需对标签做出反应?

这听起来是一个很好的模式应用程序

您将创建一个抽象基类
FileFormat
(策略接口),其中包含两个虚拟函数,
projectToXml
xmlToProject
,它们应该将内部项目表示转换为XML,反之亦然

然后创建两个实现子类
FileFormatNew
FileFormatLegacy
(这些是具体的策略)

然后,save函数还需要一个FileFormat实例,并调用该对象的相应方法来进行数据转换。您的加载函数可以通过检查XML树来选择要使用的策略,以确定它是哪个版本

当您需要支持另一种文件格式时,只需创建一个新类,它是FileFormat的子类

评论交流后的附录


当您将有很多差异非常小的版本,并且仍然希望使用策略模式时,可以将文件格式设置为多种策略的组合:圆形策略、矩形策略、线条策略等。。在这种情况下,我不会对不同版本的文件格式使用不同的类。我将为每个版本创建一个静态工厂函数,该函数返回一个带有该版本中使用的策略对象的文件格式

FileFormat FileFormat::createVersion1_0() {
    return new FileFormat(
        new LineStrategyOld(),
        new CircleStrategyOld(),
        new RectangleStragegyOld()
    );
}

FileFormat FileFormat::createVersion1_1() {
    // the 1.1 version introduced the new way to save lines
    return new FileFormat(            
        new LineStrategyNew(),
        new CircleStrategyOld(),
        new RectangleStragegyOld()
    );
}

FileFormat FileFormat::createVersion1_2() {
    // 1.2 uses the new format to save circles
    return new FileFormat(            
        new LineStrategyNew(),
        new CircleStrategyNew(),
        new RectangleStragegyOld()
    );
}

FileFormat FileFormat::createVersion1_3() {
    // 1.3 uses a new format to save rectangles, but we realized that
    // the new way to save lines wasn't that good after all, so we
    // returned to the old way.
    return new FileFormat(            
        new LineStrategyOld(),
        new CircleStrategyNew(),
        new RectangleStragegyNew()
    );
}

注意:在实际代码中,策略类名称当然会使用比“旧”和“新”更多的描述性后缀。

听起来像是你想要的。可以用来将对象保存为xml格式。从某种意义上说,这与Google Protocol Buffers和Facebook Thrift试图解决的问题是一样的……那么基本上每个对象都负责传递xml数据?这意味着我不会有一个大型方法使用公共getter和setter为不同的成员收集所有数据,而是调用一个方法“getpropertedata()”,然后从对象本身获取数据?使用这种方法,即使是两个保存版本之间最微小的更改,我也需要一种新的具体策略,它调用与上一个版本相同的所有函数,除了一个微小的更改,对吗?应始终避免冗余代码。当两种策略非常相似且仅在一些小细节上有所不同时,可以从另一种继承,也可以将大部分代码移动到基类的公共私有函数,而只做每个派生类中真正不同的部分。关于如何收集需要通过您的策略保存的数据:我需要知道您的数据是如何构造的,以便对此提供任何建议。当您希望通过为需要保存的所有内容提供getter来避免暴露项目类的太多细节时,您可以使用Visitor模式来收集数据。第一:谢谢你所有的精彩提示!第二件事是这样的:想象一下我将创建一个绘图工具。现在我编写了我的save函数,其中我保存了矩形(通过保存所有4个角的坐标)和圆(中心坐标和半径坐标),我们称之为Version1。在下一个版本中,我改变了我的结构,现在想把矩形保存一个角,宽度和高度,剩下的留着。因此,版本2可以从版本1继承。现在我更改了一个圆的保存,因此版本3继承了版本2,一切都开始混乱…当您将有很多版本,但差异非常小,并且您仍然希望使用策略模式时,您可以将文件格式设置为多个策略的组合:一个圆策略,一个矩形策略,战略等。。在这种情况下,我不会对不同版本的文件格式使用不同的类。我将为每个版本创建一个工厂方法,该方法返回一个带有该版本所需策略对象的文件格式。