2

我目前正在研究一种“保存”机制,它允许用户将他正在处理的项目保存在硬盘上。输出将是一个包含各种数据的 XML 文件。
现在我们的项目结构即将改变,我们需要编写一个新的 xml 文件(创建一个新的保存方法)。
所以现在挑战来了:保存时我希望用户能够选择他将创建的文件格式(版本1(旧)或版本2(新))。
有谁现在如何实现这一目标?周围有合适的设计模式吗?
备注: - 我们保存的数据可以看作是不相关的块,所以实际上很容易将旧块换成新块。- 事情的全部目标是,在加载旧项目时应该再次可读。(我假设这可以通过标签来完成,并且在加载时只对标签做出反应?)

4

1 回答 1

3

这听起来像是策略模式的一个很好的应用。

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

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

然后,您的保存函数将另外需要一个 FileFormat 实例,并调用该对象的相应方法来进行数据转换。您的加载函数可以通过检查 XML 树来选择要使用的策略,以获取告诉它它是哪个版本的内容。

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

补充后在评论交流

当您将拥有许多差异很小的版本并且您仍想使用策略模式时,您可以使 FileFormat 成为多种策略的组合:CircleStragegy、RectangleStrategy、LineStrategy 等。在这种情况下,我不会对不同版本的 FileFormat 使用不同的类。我将为每个版本创建一个静态工厂函数,该函数返回一个 FileFormat 以及该版本中使用的 Strategy 对象。

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()
    );
}

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

于 2012-12-14T14:30:15.060 回答