4

有人设计了依赖完整数据的代码;XML 总是包含所有元素。数据源现在正在发送稀疏 XML;如果它以前是空的,现在它就不见了。因此,是时候在修复错误的同时进行重构了。

有 100 多行这样的代码:

functionDoSomething(foo, bar, getRoot().getChild("1").getChild("A").
    getChild("oo").getContent());

除了现在,getChild("A") 可能返回 null。或者任何 getChild(xxx) 方法都可以。

作为一个额外的转折,实际上有四个单独的方法而不是 getChild(),它们只能以特定顺序出现。有人建议使用可变参数调用,这不是一个坏主意,但不会像我想的那样干净利落。

清理这个最快的方法是什么?最好的?建议在每一行周围“尝试/捕捉”,但是伙计,这很难看。将上述方法的第三个参数分解为它自己的函数可能会起作用……但这将需要 100 多个新方法,虽然不那么难看,但感觉很丑。

getChild(xxx) 调用的数量在每行 6 到 10 次之间,没有固定的深度。也没有办法为此获得正确的 DTD。稍后将在没有事先提醒的情况下添加内容,并且在发生这种情况时我希望在日志中显示警告,需要优雅地处理 XML 中的额外行。

想法?

getChild() 实际上是一种方便的方法。我想到的最干净的方法是让便捷方法返回一个有效的 Child 对象,但让那个“空”的 Child 的 getContent() 始终返回“”。

4

6 回答 6

9

请考虑使用 XPATH 而不是这种混乱。

于 2009-11-05T21:41:21.650 回答
8

您所描述的(返回一个特殊的子对象)是NullObject模式的一种形式,这可能是这里最好的解决方案。

于 2009-11-05T21:26:46.013 回答
2

解决方案是为 XML 使用 DTD 文件。它验证您的 XML 文件,因此getChild("A")当 A 是强制性的时不会返回 null。

于 2009-11-05T21:22:27.940 回答
2

怎么样:

private Content getChildContent(Node root, String... path) {
    Node target = root;
    for ( String pathElement : path ) {
         Node child = target.getChild(pathElement);
         if ( child == null ) 
            return null; // or whatever you should do

         target = child;
    }

    return target.getContent();

}

用作

functionDoSomething(foo, bar, getChildContent(root, "1", "A", "oo"));
于 2009-11-05T21:28:02.703 回答
2

您的问题可能是设计问题:得墨忒耳定律

如果不是,您可以使用类似Option 类型的东西 将 getChild 的返回类型更改为 Option<Node>:

for(Node r : getRoot())
  for(Node c1 : r.getChild("1"))
    for(Node c2: c1.getChild("A"))
      return c2.getChild("oo")

这是可行的,因为 Option 实现了 Iterable ,它会在未定义返回值时中止。这类似于 Scala,它可以用单个 for 表达式来表达。

另一个优点是您可以定义永远不会返回空值的接口。使用 Option 类型,您可以在接口定义中声明返回值可能未定义,客户端可以决定如何处理。


于 2009-11-05T21:43:37.910 回答
0

如果它总是深入到大致相同的级别,您可能可以使用 Eclipse 重构代码,例如,它会自动更改看起来相同的每一行。

这样,您可以将方法修改为更智能,而不是单独修改每一行

于 2009-11-05T21:23:57.447 回答