0

抽象クラスと具象クラスで構成された次のコードとアーキテクチャ (実際にはこれは非常に単純化されたバージョンです) があります。

public abstract class AbstractProcessor {
    public void updateDataFromUrl(String url) {
        //Download url
        //Decrypt, and do a lot of stuff, 
        String data = "abc"; //Result from downloading

        String processed = processData(data);

        //Do a lot of other things with the transformed data
    }

    public abstract String processData(String data);
}


final class ConcreteProcessor extends AbstractProcessor {
    public void updateData(int year, int month, int day) {
        String url = String.format("http://%d.%d.%d", year, month, day);
        updateDataFromUrl(url);
    }

    @Override
    public String processData(String data) {
        //Process the data

        //---------------
        //PROBLEM:
        //----------------
        //Need access to year, month, day ....

        return null;
    }
}

メソッドには、いくつかのプロセッサで再利用したいupdateDataFromUrl多くのコード (ブース、呼び出しの前後) が含まれています。このため、コードを抽象クラスに入れました。processData

問題は、新しく追加されたメソッド (ここでは 、、 )に提供されたデータにアクセスしたいということです。これらのパラメーターを知らない抽象クラスを呼び出しが流れると、この情報が失われます。このアーキテクチャを変更して、この情報を保持するにはどうすればよいですか?updateDatayearmonthday

次の解決策が思い浮かびましたが、すべて明らかな欠点があります。

  1. 抽象メソッドに URL を指定し、そこからパラメーターを再度抽出します。(問題: メソッドでのみ必要でprocecssData、URL では不要なパラメーターは何ですか?)
  2. updateDataFromUrlメソッドを 2 つの 2 つのメソッド (呼び出し前の部分と呼び出し後の部分) に分割しprocessDataます。これらのメソッドを ConcreteProcessor で直接使用します。(問題:updateDataFromUrlメソッドには、呼び出しの前後に必要なコンテキストがたくさんありますprocessData。新しく作成されたメソッド間でこのデータを転送するにはどうすればよいですか?)
4

2 に答える 2

2

2つのアイデア:

  1. でインスタンス変数を使用しConcreteProcessorて、年、月、日を格納します。どちらのメソッドも、オブジェクトのインスタンス変数にアクセスできます。ただし、抽象クラスにはアクセスできません。注意:オブジェクトはもはやスレッドセーフではありません。データを同時に処理するには、複数の独立したプロセッサが必要です。

  2. 依存関係を逆にして、構成を使用します。ジェネリッククラスProcessorには共通論理が含まれています。呼び出すと、実装updateDataFromUrlするのインスタンスも渡します(実際には一種のコールバック)。ProcessingStrategyprocessData

考えられるアイデアには、おそらくいくつかのバリエーションがあります。

于 2012-11-22T14:24:40.463 に答える
1

マイナーな変更のみがこの解決策につながります (あるポイントを見逃していない場合 (テストされていない場合))。

次の利点があります。

  • 情報の受け渡しは非常に簡単です (インスタンス変数を使用)
  • スレッドセーフを保持します
  • 外部(パブリック)ビューから、ConcreteProcessor不変のままにすることができます

ConcreteProcessorfromを返すのではupdateDataなく、変換されたデータを表す不変の型を返すのがおそらく最善でしょう。

public abstract class AbstractProcessor {
    public void updateDataFromUrl(String url) {
        //Download url
        //Decrypt, and do a lot of stuff, 
        String data = "abc"; //Result from downloading

        String processed = processData(data);

        //Do a lot of other things with the transformed data
    }

    public abstract String processData(String data);
}


final class ConcreteProcessor extends AbstractProcessor {
    public static ConcreteProcessor updateData(int year, int month, int day) {
            ConcreteProcessor p = new ConcreteProcessor(year, month, day);
            p.updateDataFromUrl(url);
            return p;
    }

    private /* instance vars for year, month, day, url, ... */

    private ConcreteProcessor(int year, int month, int day) {
            this.year = year;
            this.month = month;
            this.day = day;
            this.url = String.format("http://%d.%d.%d", year, month, day);
    }


    @Override
    public String processData(String data) {
        //Process the data

        //---------------
        // NO PROBLEM:
        //----------------
        //Easy to access to year, month, day using the instance vars

        return null;
    }
}

しかし、全体的な概念は線形パイプラインのように見えるため、パイプラインをより明示的にするのがおそらく最善でしょう。ある種の状態を運ぶ必要がありますが、ジェネリックを使用しても大きな問題にはならないと思います。

于 2012-11-22T14:52:40.967 に答える