4

バックグラウンド

私は次のような状況にいます:

Analyzerおおよそ次のようなタイプがあります

interface Analyzer {
    int computeValue();
    String performAnalysis();
}

のようなものによって実装

class AnalyzerImpl implements Analyzer {

    @Override
    public int computeValue() {
        return 5;
    }

    @Override
    public String performAnalysis() {
        return "Result: " + computeValue();
    }
}

(私の実際のコードでは、さまざまな複雑さのperformAnalysisいくつかの異なるcomputeValue方法を使用して多くの計算を実行します。)

ここで、実行時にオブジェクトの動作を選択的に微調整する必要がありAnalyzerます (または、微調整された動作でラッパーを作成します)。

私が試したこと:

微調整方法を追加しました:

public Analyzer tweakAnalyzer(Analyzer untweakedAnalyzer) { ... }

デコレータパターンを使用して解決しようとしました:

class AnalyzerDecorator implements Analyzer {
    Analyzer delegate;
    public AnalyzerDecorator(Analyzer delegate) {
        this.delegate = delegate;
    }

    @Override
    public int computeValue() {
        return delegate.computeValue();
    }

    @Override
    public String performAnalysis() {
        return delegate.performAnalysis();
    }
}

tweakAnalyzer次に、次のように実装しました。

public Analyzer tweakAnalyzer(Analyzer untweakedAnalyzer) {
    return new AnalyzerDecorator(untweakedAnalyzer) {
        @Override
        public int computeValue() {
            return 1337;              // tweaked value!
        }
    };
}

ただし、行うときは

tweakAnalyzer(new AnalyzerImpl()).performAnalysis();

調整されていない値 が得られますが、希望どおりResult: 5ではありませんResult: 1337

(これは、微調整されたアナライザーが微調整されていないアナライザーと同じオブジェクトではなく、単にラッパーであるためです。そのため、 in の呼び出しがcomputeValue意図したとおりにAnalyzerImpl機能しません。)

完全な ideone.com の例。

TL;DR:

実行時のオブジェクトの動作を微調整したい。デコレータ パターンを使用しましたが、すべての仮想メソッドが「失われました」。

質問:

この問題を解決する最善の方法は何ですか?つまりAnalyzer、仮想メソッドのルックアップを失わないように、または失われても問題にならないように、の動作を微調整するにはどうすればよいでしょうか?

4

2 に答える 2

5

問題はperformAnalysis、クラスを装飾したことがわからないため、デコレータが呼び出されないことです。

おそらくperformAnalysis、 とcomputeValueを 2 つのクラス ( AnalyzerwithperformAnalysisCalculatorwith computeValue)に分割する必要があります。

そうすれば、それらを個別に装飾し、装飾された電卓をAnalyzera'laに渡すことができますperformAnalysis(Calculator calculator)

IDEOneの例。はい、基本的には戦略パターンが実行されています。

于 2012-08-26T07:57:25.203 に答える
1

アナライザー オブジェクトのコードにアクセスできますか? その場合は、戦略パターンを使用して微調整できるように設計できます。

代替 (種類の複数のディスパッチを含むテンプレート パターン):

abstract class Analyzer {

   public final int ComputeValue () {
      return doComputeValue (this);
   }

   public final string PerformAnalysis () {
      return doPerformAnalysis (this);
   }

   protected abstract int doComputeValue (Analyzer myself);
   protected abstract string doPerformAnalysis (Analyzer myself);
}

class AnalyzerImpl extends Analyzer {

   protected int doComputeValue (Analyzer myself) {
      ...
   }

   protected string doPerformAnalysis (Analyzer myself) {
      return "Result: " + myself.ComputeValue();
   }
}

class AnalyzerDecorator extends Analyzer {
    Analyzer delegate;
    ...
    protected string doPerformAnalysis (Analyzer myself) {
        return delegate.doPerformAnalysis (myself);
    }
    protected int doComputeValue (Analyzer myself) {
        return delegate.doComputeValue (myself);
    }
}
于 2012-08-26T08:05:10.450 に答える