假设我们要将 XML 消息解析为业务对象。我们将流程分为两部分,即:
-将 XML 消息解析为 XML 语法对象。 -将 XML 对象转换为业务对象。
第一部分是自动完成的,为每个节点生成一个语法对象。
到目前为止,第二部分是按照 XML 架构完成的。示例:
如果我们有 XML 消息(简体):
<Main>
<ChildA>XYZ</ChildA>
<ChildB att1="0">
<InnerChild>YUK</InnerChild>
</ChildB>
</Main>
我们可以找到以下类:
DecodeMain(Calls DecodeChildA and B)
DecodeChildA
DecodeChildB(Calls DecodeInnerChild)
DecodeInnerChild
当我们需要处理相同消息的多个版本时,主要问题就来了。假设我们有一个新版本,其中只有 DecodeInnerChild 发生了变化(例如:我们需要在值的末尾添加一个“a”)
真正重要的是,解决方案要能适应更多版本并尽可能干净。我考虑了以下选项:
1)简单继承:创建两个类DecodeInnerChild。每个版本一个。
缺点:我需要为每个父类创建不同的类来调用正确的类。
2)版本参数:给每个方法添加一个对象,版本作为参数。这样我们就可以知道根据每个版本在每个方法中做什么。
缺点:一点都不干净。不同版本的代码混在一起。
3)Inheritance + Version Parameter:为直接变化的节点(如InnerChild)创建2个带有公共(public)代码基类的类,并在每个方法中添加版本作为参数。当一个节点调用另一个类来解码子对象时,它将根据 Version 参数使用一个或另一个类。
4)某种执行者模式(我不知道该怎么做):在开始时定义某种规范对象,其中指出了所有将要使用的方法,我将这个对象传递给负责执行它们的类。
你会怎么做?欢迎提出其他想法。
提前致谢。 :)
最佳答案
How would you do it? Other ideas are welcomed.
与其自己解析 XML,我不如让像 CodesynthesisXSD 这样的东西作为第一步为我生成所有需要的类并处理这些类。稍后当性能或其他问题出现时,我可能会开始四处寻找更高效的解析器,如果这没有成果,我就会开始为特定情况设计和编写自己的解析器。
编辑:
Sorry, I should have been more specific :P, the first part is done automatically, the whole code is generated from the XML schema.
好吧,让我们讨论一下如何处理随着软件的发展你最终也会进化输入的通常情况。我把所有的银弹和魔法棒都放在 table 上了。是否以及您实现它们完全取决于您。
- 版本属性 无论如何,我创建的大多数东西都有。 before 向后兼容性问题无法优雅地解决是理智的。最重要的是,它实现了当旧软件无法解析新输入时,它会产生对每个人都立即有意义的投诉。
- 我通常还会为converter 添加一些接口(interface)。因此,当旧软件无法解析输入时,可以配备来自较新版本输入的转换器。新软件也可以使用相同的转换器来解析旧的输入。另外,它是从完全“外来”输入插入转换器的地方。双赢的局面。 ;)
- 在微小变化的特殊情况下,我会考虑使新的
DecodeInnerChild
内部更灵活是否便宜,因此接受带有或不带有“a”的值作为有效值。在转换器中,我仍然需要在转换旧版本时去掉那个“a”。 - 通常实际发生的情况是
InnerChild
确实拆分并且两个版本将并排使用。如果两个InnerChild
之间存在足够的行为差异,那么就没有必要避免多态InnerChilds
。当添加多态性时,确实就像您在 1) 中所说的那样,所有包含现在具有此类多态成员的类都必须更改。在这种情况下,转换器通常应该生成残缺的InnerChild
或转发到输入超出其能力范围的旧版本。
关于c++ - 解析不同的 xml 消息。版本,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/13104347/