有人设计了依赖于完整数据的代码; XML始终具有每个元素。数据源现在发送稀疏XML;如果之前它已经空了,那么它现在已经丢失了。因此,是时候在修复错误的同时进行重构了。
这样有100多行代码:
functionDoSomething(foo, bar, getRoot().getChild("1").getChild("A").
getChild("oo").getContent());
除此之外,getChild(“A”)可能会返回null。或者任何getChild(xxx)方法都可以。
作为一个额外的转折,实际上有四种不同的方法,而不是getChild(),它们只能在某些订单中出现。有人提出了一个varargs调用,这不是一个坏主意,但不会像我想的那样干净利落。
清洁这个最快的方法是什么?最好的?建议在每条线附近“尝试/捕捉”,但男人,那是丑陋的。将上述方法的第三个参数分解为它自己的函数可以起作用......但这需要100多个新方法,这些方法感觉很难看,尽管不那么简单。
getChild(xxx)调用的数量介于每行6到10之间,没有固定的深度。也没有办法为此获得正确的DTD;事情将在以后没有事先抬头的情况下添加,并且当发生这种情况时我更喜欢日志中的警告,需要优雅地处理XML中的额外行。
想法?
getChild()实际上是一种方便的方法。我想到的最简洁的方法是让方便方法返回一个有效的Child对象,但让那个“空”Child的getContent()总是返回“”。
答案 0 :(得分:9)
请考虑使用XPATH而不是这个混乱。
答案 1 :(得分:8)
你所描述的(返回一个特殊的子对象)是NullObject模式的一种形式,这可能是最好的解决方案。
答案 2 :(得分:2)
解决方案是使用XML的DTD文件。它验证您的XML文件,因此当A是必需的时,getChild("A")
不会返回null。
答案 3 :(得分: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"));
答案 4 :(得分:2)
您的问题可能是设计问题:Law of Demeter。
如果没有,您可以使用Option type之类的内容将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类似,它可以在单个表达式中表达。
另一个优点是您可以定义永不返回空值的接口。使用Option类型,您可以在接口定义中声明返回值可能未定义,客户端可以决定如何处理它。
答案 5 :(得分:0)
如果它总是向下钻到大致相同的级别,你可以使用Eclipse重构代码,并且它会自动更改看起来相同的每一行。
通过这种方式,您可以将方法修改为更智能,而不是单独修改每一行