2

いくつかのコードを書き直して、いくつかの結合の問題を解決し、将来の変更を容易にしようとしています。

現在、状況に応じて適切な実装を選択する基本クラスに静的ファクトリ メソッドがあります。決定は、専門の程度に基づいています。

タイプ A と B はどちらもこれを処理できますが、B はこの状況のた​​めに特別に設計されており、正しい選択です。

したがって、基本クラスはすべての実装と密接に結合されており、このメソッドは、新しい特殊な実装が作成されたときに書き直す必要があります。

Chain of Responsibilityパターンを使用して、この結合を断ち切ることを考えています。ただし、最も適切な実装が確実に実行されるようにする方法がわかりません。この決定を実装に委ねると、同じ結合の問題が発生せずに特殊化の順序でクエリが実行されることを保証できません。

このような状況を処理するためのパターンや方法はありますか? (私の最善の推測では、展開を妨げるでしょう。誰もが「そうです、それがそれを行う唯一の方法です!」と言わないように、私はそれを後ろのポケットに入れておきます。)

4

5 に答える 5

2

実装が特定の状況をどのように処理できるかを定量化する方法がある場合は、ChainofResponsibilityのバリエーションを使用できます。

個々の実装は、特定の入力セットを処理する能力の定量化されたランキングを提供でき、このランキングを使用して、使用する「最良の」実装を選択できます。

ただし、これは必ずしも優れた設計ではありません。個々の実装に多くの信頼を提供し、特定の状況をどれだけうまく処理できるかについて「正直」である必要があります。複数の実装が同じ値を報告する状況に陥る可能性もあります。その場合、何らかの選択方法を選択する必要があります。

于 2010-10-11T16:49:03.073 に答える
1

解決策は、責任の連鎖と訪問者のパターンのハイブリッドである可能性があります。訪問者は、一般的な行動の側面のいくつかを抽象化することができます。

于 2010-10-26T21:20:36.377 に答える
1

ケースごとに何らかの適切な順序付け関数を定義できる場合は、各クラスに型固有のファクトリと一緒に自己を登録させ、それに基づいて並べ替えることができます。

class Base;
class CaseInfo;

class TypeFactory {
 public:
  virtual Base MakeOne();

  //... Anything needed to implement Compare
}

// each derived type must inject a instance into AllTypes
dequeue<TypeFactory> AllTypes;

bool Compare(const TypeFactory&, const TypeFactory&, const CaseInfo&);
Base Best(const CaseInfo&);

私が考えることができる唯一の問題は、比較が自明ではないということです。どの CaseInfo についても、最適な一致を一意に選択する必要があります。トリックは、「その他」ビットを選択することです。

于 2010-10-26T16:02:50.577 に答える
0

いくつかのランタイムデータに基づいて利用可能な多くの実装から1つの特定の実装を作成する必要があります。これは、AbstractFactoryパターンのように聞こえます。

于 2010-10-11T16:47:50.797 に答える
0

責任の連鎖がこのようにモデル化できるかどうかはわかりません。一連の責任のハンドラーは、2 つのことしかできません。リクエストを処理するか、次のハンドラーに渡します。どのハンドラーが次に来るか、または誰がリクエストを処理する必要があるかはわかりません。それができないことだけを知っています。

ハンドラーはより選択的である必要があります。IE ウィンドウを処理するハンドラーと Java アプリを処理するハンドラーがある場合、2 つのハンドラーは、処理しているウィンドウの種類を検出できる必要があります。IE ハンドラーは、ウィンドウが IE であるかどうかをチェックします。それが渡されない場合は、別の場所で処理されても気にしません。処理できないことを認識しているだけです。

私の提案は、1 つのウィンドウ タイプのみを処理する特定のハンドラを作成することです。ジェネリック ハンドラを 1 つ作成します。次に、ジェネリック ハンドラーが最後になるようにハンドラーを並べ替えます。特殊なハンドラーは最初にそれを実行しようとします。何も見つからない場合は、汎用ハンドラーが要求を処理します。

提案したことを本当に実行したい場合は、ハンドラーに複数のパスを作成できます。1 を渡すと、非常に特殊なウィンドウのみが捕捉されます。Pass 2 あまり専門化されていないウィンドウが引っかかります。パスを作るのに飽きるまでなどなど。ただし、私にとっては... 1つのハンドラーで多くのことをしようとしないでください。各ハンドラが 1 つのウィンドウを担当する場合、順序は問題ではなく、常に正しいウィンドウ タイプを処理します。不明なウィンドウはすべて、ジェネリック ハンドラーによってキャッチされます。

于 2010-10-26T21:00:44.110 に答える