1

Web サービスと同期する必要がある一連のアプリがあります。

  1. Web サービスから XML をダウンロードします。
  2. その XML を解析します。
  3. 次に、解析された XML と一致するようにデータベースを更新します。

重複を避けるために、できるだけ多くの関連コードを共通ライブラリに保持したいと考えています。また、さまざまなアプリがすべて、コードの解析と更新をかなり単純な共通フレームワークにスロットインしたいと考えています。

したがって、一般的な sync() メソッドがあります。

public void sync(URI updateUrl, XMLParser parser, Updater animalUpdater) {
    String raw = getXML();
    List<ParsedAnimal> parsed = parser.parse(raw);
    // try:
    // begin transaction
    for (ParsedAnimal pi : parsed) {
        animalUpdater.updateItem(pi);
    }
    // commit transaction
    // catch: rollback transaction, rethrow
    // finally: close database connection
}

パーサーは、ParsedCat、ParsedDog、またはその他のいずれかを返します。これらはすべて、共通の ParsedAnimal クラスから継承されます。

public abstract class ParsedAnimal {...}
public class ParsedCat extends ParsedAnimal {...}
public class ParsedDog extends ParsedAnimal {...}

次に、解析されたアイテムを取得し、コンテンツをデータベースに挿入する必要があるアップデーターがあります。

public abstract class Updater {
    public abstract void updateItem(ParsedAnimal parsed);
}
public class CatUpdater extends Updater {
    @Override
    public void updateItem(ParsedCat parsed) {}
}
public class DogUpdater extends Updater {...}

これは機能しません — Updater のコントラクトは updateItem() が ParsedAnimal を受け入れることを指定しており、CatUpdater と DogUpdater はどちらも特定の種類の動物のみを受け入れることでそのコントラクトを破っています。

私が持っているのは並列クラス階層です — ParsedX は XUpdater と 1 対 1 で一致します。Coding HorrorのCode Smellsのページでは、2 つのクラス階層を 1 つの階層に統合することを提案していますが、「作業中のもの」と「作業中のもの」は十分に異なるため、別のクラスにする必要があるように感じます。

これを構造化するきちんとした方法、または便利な設計パターンはありますか?

4

2 に答える 2

4

Updaterジェネリックは、コントラクトの問題に役立ちます。

public abstract class Updater<T extends ParsedAnimal> {
    public abstract void updateItem(T parsed);
}
public class CatUpdater extends Updater<ParsedCat> {
    @Override
    public void updateItem(ParsedCat parsed) {}
}
public class DogUpdater extends Updater<ParsedDog> {...}

ただし、syncメソッドには、Updater解析されたすべてのアイテムに使用しようとするパラメーターがあります。これはうまくいきません。解析されたタイプごとに個別にUpdater作成する場合は、取得した解析結果に基づいてアップデーターをインスタンス化する必要があります。これは、何らかの形の「ファクトリー」で処理できます。手始めに、 Factory Methodパターンの使用を検討することをお勧めします。

于 2012-10-29T00:20:46.297 に答える
0
updateItem(ParsedAnimal parsed){
    if (parsed instanceof ParsedCat) {
        ... 
    } else if (parsed instanceof ParsedDog) {
        ... 
    } 
} 
于 2012-10-29T00:23:56.860 に答える