1

メッセージタイプの基本クラスをパラメーターとして受け取る「通知」メソッドを持つプロセスがあります。メッセージの派生型に基づいて異なる処理をしたいと思います。これは、「プロセス」と呼ばれるメソッドまたはメッセージ タイプに似たものを追加し、ポリモーフィズムを使用して呼び出す必要があるということですか? 特定のメッセージ タイプごとに「通知」を追加する方がよいでしょうか。

詳細: 言語は C++ です。ここでは通知を使用することをお勧めします。これにより、さまざまなメッセージの種類を通知するメソッドが 1 つだけで済みます。コントローラーは、純粋な viual notify(MsgBaseClass) メソッドを指定するリスナー クラスから継承します。新しいメッセージの種類ごとに通知を追加する必要がないので、私は今でもそのアイデアを気に入っています。しかし、コントローラ コード自体では、動的キャストやメッセージ タイプのメッセージへの追加以外に、メッセージ タイプを区別する方法がわかりません。

編集: 訪問者パターンを使用すると思います。これにより、通知用のメソッドを 1 つだけ保持でき、コード内の switch ステートメントを回避できます。「ビジター」インターフェースは、さまざまな派生メッセージ・タイプを処理するためにリスナーが必要とするさまざまなメソッドを指定します。これには、純粋な仮想 "accept(MyMessageTypeVisitor v)" という 1 つのメッセージのみを Message ベース クラスに追加する必要があります。派生メッセージ クラスは、v.visit(this); を使用してそれを実装します。

これはうまくいくはずだと思います

4

4 に答える 4

1

従来のOOの回答では、基本メッセージクラスが、特定の処理を提供するために具体的なメッセージサブクラスがオーバーライドする抽象メソッドを提供する必要があります。

DylanやCLispなどの一部の(あまり普及していない)言語は、問題を大幅に解決する「ジェネリック関数」(引数型に動的にディスパッチされる)を提供します。

人気のある言語で実行可能な柔軟なアプローチの1つは、ボブおじさんの「非巡回ビジター」デザインパターンです。http: //www.objectmentor.com/resources/articles/acv.pdf ; その他の訪問者のバリエーションについては、www.ccs.neu.edu / research / demeter/adaptive-patterns/visitor-usage/papers/plop96/variations-visitor-nordberg.psを参照してください。

于 2009-05-02T16:54:26.233 に答える
1

編集: dirkgently には良い点があり、メッセージは自分自身を処理する方法を知っているべきではないと思います。したがって、メッセージをファクトリとして使用できる場合に説明したアプローチは、良い考えではありません。ただし、抽象的なプロセス ファクトリは良い解決策になると思います。

抽象ファクトリを使用して、処理を処理できるオブジェクトを作成し、ポリモーフィズムを使用してそれを呼び出します。このファクトリは、メッセージ クラスに直接含めることも、メッセージ タイプをパラメータとして受け取り、適切なオブジェクトを返す別のファクトリ クラスを作成することもできます。

class Message {
public:
  virtual Processor *getProcessor() = 0;
  // other methods
};

class Processor {
public:
  virtual void doWork() = 0;
};

class MyListener : Listener {
public:
  void notify(Message *message);
};

void MyListener::notify(Message *message) {
  Processor *proc = message->getProcessor();
  proc->doWork();
};

(これが正しくない場合は申し訳ありません。私の C++ は少し弱いですが、原理を示していると思います。)

これにより、メッセージ タイプごとに getProcessor() をオーバーライドし、適切なプロセッサを作成することができます。

IMVHO、ポリモーフィズムがその道です。実行したい処理ロジックの種類はメッセージ クラスに属しておらず、別のクラスに移動する必要があると思います。このアプローチを好むもう 1 つの理由は、メッセージを追加する場合に、通知されるクラスの構造を変更する必要がないことです。メッセージの種類が 1 つまたは 2 つしかない場合、これは問題にならない可能性があります。

于 2009-05-02T16:42:21.600 に答える
0

次のようなことができます。

DerivedType *dt = dynamic_cast< DerivedType >( &BaseType );
if( dt != NULL )
{
    // Handle processing of DerivedType
}

処理された DerivedType ごとに dynamic_cast を実行してみてください。null 以外のポインターを取得した場合は、キャストしようとした型を受け取ったことがわかります。

于 2009-05-02T16:50:04.480 に答える
0

オブザーバーのデザイン パターンにこだわっていますか?

オーバーロードnotifyが候補のようです。オブザーバー パターンは非常に単純です。これは、ハリウッドの原則、つまり「電話しないで、電話します!」に基づいています。アイデアは、一連のオブジェクト (オブザーバー) を持ち、それらにクエリを実行させる代わりに通知することです。Event一般的な種類のデータをオブザーバーに渡します。これをどうするかは観察者に委ねるべきです。オブザーバーがさまざまなイベントに反応する場合は、いくつかありdynamic_castsます (はい、イベント階層も必要です)。

于 2009-05-02T16:44:01.110 に答える