我目前正在开发一种“保存”机制,允许用户将他正在处理的项目保存在硬盘上。输出将是包含各种数据的XML文件
现在我们的项目结构即将发生变化,我们需要编写一个新的xml文件(创建一个新的保存方法)
所以现在遇到了挑战:保存时我希望用户能够选择他将要创建的文件格式(版本1(旧)或版本2(新))。
现在有人如何实现这一目标?周围是否有合适的设计模式?
备注:
- 我们保存的数据可以看作是不相关的块,因此实际上很容易用新的块交换旧块。
- 事情的整个目标是,在加载旧项目时它应该是可读的。 (我假设这可以通过标签来完成,并且在加载时只对标签做出反应?)
答案 0 :(得分:3)
这听起来像是Strategy模式的一个很好的应用程序。
您将使用两个虚函数FileFormat
和projectToXml
创建一个抽象基类xmlToProject
(策略接口),它们应该将您的内部项目表示形式转换为XML或副本反之亦然。
然后创建两个实现子类FileFormatNew
和FileFormatLegacy
(这些是具体策略)。
然后,您的保存功能还需要一个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()
);
}
注意:在实际代码中,您当然会为策略类名称使用比“旧”和“新”更多的描述性后缀。