0

私は起動具象クラス関数に

EvaluatorA : IEvaluator 
EvaluatorB : IEvaluator 
EvaluatorC : IEvaluator 

唯一の機能を有しているIEvaluatorインタフェースの共通インタフェースを実装するには、以下の具体的なクラスがある - Evaluate、評価者のすべての3つのタイプに実装されています。そして、私は構成に基づいて評価者を呼び出すドライバクラスを持っていますが、それはIEvalutorへの(設計によって)アクセスしか持たない、つまり、どの具体的な評価者が現在呼び出されているかを知る必要はありません。評価者の一つは、EvaluatorCを言う時に問題が発生し

、新しい機能Predictを実装する必要がある、と私の要件は、EvaluatorCため、Predict機能はEvaluateを呼び出した後に呼び出される必要があります。

一時的な解決策1:

// evaluator is previously instanciated 
evaluator.Evaluate(); 
if (evaluator is EvaluatorC) 
    evaluator.Predict(); 

、これはきちんとしていないあなたが見ることができるとおり: 一つの解決策は、評価者の種類を確認することです。明日、私はEvaluatorBのためだけに別の関数Danceを呼び出す必要があり、EvaluatorAEvaluatorBの両方に対してSingの関数を呼び出すと、それは乱雑になります。

時間的な解決策2: Add関数インタフェースIEvaluatorからPredict、および他の評価のためには、ちょうど空のボディを持つ関数を実装します。これはvoidの戻り値型関数では機能しますが、戻り値の型がvoidでない場合は、ドライバプログラムで追加の安全性チェックが必要です。さらに、空のボディを持つ関数をプレースホルダとしてだけ持つのは良い考えであるかどうかはわかりません。

時間的解決法3: インターフェイスを抽象クラスに変更します。これはソリューション2と似ていますが、デフォルトの実装はPredictです。しかし、私はこのアプローチがプロジェクトの元の構造を変更し、解決策2に比べて多くの利益をもたらさないため、どちらの方法も気に入らなかった。

全体として、私はこの問題に対する満足のいく解決策を持っていない。 decoration patternが助けてくれることを願っています(しかしわかりません)。この問題は、プログラミング言語に固有の問題ではありません。あなたのアイデアを共有してください。

編集1:評価担当者の責任に関する詳細を追加 評価者は、特定のソリューションを評価し、いくつかの指標を返すことになっています。評価指標を取得した後、ドライバプログラムはレポート作成などのハウスキーピング作業を行いますが、これはすべての評価者にとって必要であることに注意してください。そして、評価者(EvaluatorC)の1人は、生成されたレポートに基づいてPredict()を呼び出す必要があります。しかし、他の評価者はこのステップを必要としません。

+0

なぜ、 'EvaluatorC'の' Evaluate'メソッドで 'Predict'を呼び出さないのですか? – sdgfsdh

+0

@sdgfsdh、良い点。これは最初の計画ですが、 'Evaluate()'を呼び出した後、ドライバープログラムで行う必要のあるハウスキーピング作業があることがわかります。 'Predict()'はそれ以降にしか呼び出せません。 – Lin

+0

その後、ドライバは 'Evaluate'メソッドでも動作しますか?あなたの問題の正しい抽象化がまだ見つかりませんでした。 – sdgfsdh

答えて

0

私たちはデザインパターンについて話しているので、あなたが記述していることはtemplate method patternを思い起こさせると思います。

基本はアルゴリズムのスケルトンを基本クラスに定義し、サブクラスが特定のステップを実装するかどうかを選択できるようにすることです。ここに例があります。

abstract class EvaluatorPredictor { 
    void evaluateAndPredict() { 
    evaluate(); 
    predict(); 
    } 

    protected void evaluate() { 
    // no-op 
    }; 

    protected void predict() { 
    // no-op 
    }; 
} 

class AEvaluator extends EvaluatorPredictor { 
    protected void evaluate() { 
    System.out.println("I implement this"); 
    } 
} 

class BEvaluator extends EvaluatorPredictor { 
    protected void evaluate() { 
    System.out.println("I implement this"); 
    } 


    protected void predict() { 
    System.out.println("I implement this too"); 
    } 
} 

より多くのパワーを得ることができます。たとえば、EvaluatorPredictor、またはそのクラスのいずれかのクラスでは、EvaluatorPredictorインターフェイスをそれぞれ実装する2つのオブジェクトを使用できます。

class Whatever { 
    constructor(e Evaluator, p Predictor) { 
    this.e = e; 
    this.p = p; 
    } 

    void evaluateAndPredict() { 
    this.e.evaluate(); 
    this.p.predict(); 
    } 
} 

PS。私の貧弱なJavaのような構文を許してください。メソッドの宣言やアクセス修飾子にエラーがあると確信しています。上記が役立つことを願っています。

関連する問題