4

誰かが完全なデータに依存するコードを設計しました。XMLには常にすべての要素が含まれていました。データソースは現在、スパースXMLを送信しています。以前は空だったとしたら、今はなくなっています。だから、バグを修正しながらリファクタリングする時が来ました。

次のような100行以上のコードがあります。

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

今を除いて、getChild( "A")はnullを返す可能性があります。または、getChild(xxx)メソッドのいずれかが可能性があります。

1つの追加の工夫として、getChild()の代わりに、実際には4つの別個のメソッドがあり、これらは特定の順序でのみ発生する可能性があります。誰かがvarargs呼び出しを提案しました。これは悪い考えではありませんが、私が望むほどきれいには機能しません。

これをクリーンアップする最も簡単な方法は何ですか?最高の?すべての行の周りに「試して/キャッチ」することが提案されましたが、それは醜いです。上記のメソッドの3番目の引数を独自の関数に分解することは機能する可能性があります...しかし、それは100以上の新しいメソッドを必要とし、それほどではありませんが、醜い感じがします。

getChild(xxx)呼び出しの数は、1行あたり6〜10の範囲であり、深さは固定されていません。これに対して正しいDTDを取得する方法もありません。事前の注意なしに後で追加される予定です。その場合にログに警告を表示したい場合は、XMLの余分な行を適切に処理する必要があります。

アイデア?

getChild()は、実際には便利なメソッドです。私が考えている最もクリーンな方法は、コンビニエンスメソッドが有効な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

あなたの問題は設計上の問題である可能性があります:デメテルの法則

そうでない場合は 、getChild の戻り値の型を Option<Node> に変更するOption 型のようなものを使用できます。

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

これは、Option が Iterable を実装しているため、戻り値が定義されていない場合に中止されるため機能します。これは、単一の for 式で表現できる Scala に似ています。

もう 1 つの利点は、null 値を決して返さないインターフェースを定義できることです。Option 型を使用すると、戻り値が未定義である可能性があり、クライアントがこれを処理する方法を決定できることをインターフェイス定義で述べることができます。


于 2009-11-05T21:43:37.910 に答える
0

常にほぼ同じレベルにドリルダウンする場合は、たとえばEclipseを使用してコードをリファクタリングすると、同じように見えるすべての行が自動的に変更されます。

そうすれば、各行を個別に変更するのではなく、メソッドをよりスマートに変更できます。

于 2009-11-05T21:23:57.447 に答える