問題タブ [double-dispatch]
For questions regarding programming in ECMAScript (JavaScript/JS) and its various dialects/implementations (excluding ActionScript). Note JavaScript is NOT the same as Java! Please include all relevant tags on your question; e.g., [node.js], [jquery], [json], [reactjs], [angular], [ember.js], [vue.js], [typescript], [svelte], etc.
c++ - RTTI なしで「拡張可能」な C++ ダブル ディスパッチ
RTTI と dynamic_cast<> を使用せずに C++ で二重ディスパッチを正しく処理する方法と、クラス階層が拡張可能なソリューション、つまり基本クラスをさらに派生させることができ、その定義/実装がそれについて知る必要がありますか?
仕方がないと思いますが、間違っていることが証明されてうれしいです:)
java - ビジターパターンでダブルディスパッチはどのように機能しますか?
訪問者パターンに関連する他の質問を調べていましたが、訪問者パターンでの二重ディスパッチの実装を理解できませんでした。
リンクを参照してください ビジターパターン
訪問者パターンで二重ディスパッチはどのように機能しますか?
c++ - Equals()のC++ダブルディスパッチ
派生クラスとを含む抽象基本クラス があると想像してください。Shape
Circle
Rectangle
Shape*
2つのポインターがあると仮定して、2つの形状が等しいかどうかを判断する必要があります。(これは、のインスタンスが2つありvector<Shape*>
、それらが同じ形状であるかどうかを確認したいためです。)
これを行うための推奨される方法は、ダブルディスパッチです。私が思いついたのはこれです(ここでは非常に単純化されているため、形状は同じタイプの他のすべての形状と同じです):
これは機能しますが、派生クラスごとに個別のequals
関数とfriend
宣言を追加する必要があります。次に、まったく同じ関数を各派生クラスにShape
コピーして貼り付ける必要があります。これは、たとえば10種類の形状の場合、非常に多くの定型文です。equals
それを行うためのより簡単な方法はありますか?
dynamic_cast
問題外です。遅すぎる。(はい、ベンチマークしました。アプリでは速度が重要です。)
私はこれを試しましたが、機能しません:
equals()
同じ形状であっても、常にfalseを返します。is_equal(Shape&)
「より具体的な」一致が利用可能な場合でも、ディスパッチは常に基本機能を選択しているようです。これはおそらく理にかなっていますが、理由を理解するのに十分なほどC++ディスパッチを理解していません。
c++ - C++のInputMapのダブルディスパッチが失敗する-コードが単純化された
こんにちは、私の現在のプロジェクトの1つで、InputMapを実装したいと思います。だから私は抽象的な入力を持っています
およびInputMap
これまでのところ良好です-ここには機能がありません。ここで、抽象入力クラスから最初の実際の入力を導出します。
これが私の派生したInputMapです
そしてここにテストがあります:
input.Dispatch(&map)
もちろん、それがを呼び出すことを期待していますmap.HandleInput(StringInput input)
が、残念ながら、デフォルトのハンドラーは常に呼び出されます。このパターンを間違ってプログラムしましたか?みんなありがとう、私は自分のコードをずっと見つめてきました、しかし私はそれを見ません。
c++ - C++ ダブル ディスパッチ オブザーバー通知
現在トラブルシューティング中のコードは次のとおりです。
したがって、コードが実行され、CTimer::notify()
呼び出され、それが を作成TimerNotification
してオブザーバーに渡します。オブザーバーreadNotification()
は、通知のread()
メソッドを呼び出します。オブザーバーは、最終的にオブザーバーの (できれば) 正しいupdate()
メソッドを呼び出します。
最後のステップは失敗です。update(INotification&)
目的のメソッドの代わりにメソッドを呼び出しますupdate(ITimerNotification&)
。
この試行された Double Dispatch パターンが機能するために、ここで何が欠けていますか? 適切な関数呼び出しを選択するための正しい型情報を取得していないようです。
助けてくれてありがとう!
scala - switchステートメントを使用せずに、2つのオブジェクトのタイプに基づいてScala/Javaで正しいメソッドを呼び出す方法は?
私は現在、すべて GameEntity クラスから継承する多数のエンティティ (GunBattery、Squadron、EnemyShip、EnemyFighter など) がある Scala でゲームを開発しています。ゲーム エンティティは、イベント/メッセージ システムを介して、関心のあるものをゲームの世界にブロードキャストし、相互にブロードキャストします。多くの EventMesssages (EntityDied、FireAtPosition、HullBreach) があります。
現在、各エンティティには、receive(msg:EventMessage)
応答するメッセージ タイプごとに固有の受信メソッド (例: receive(msg:EntityDiedMessage)
) があります。一般的なreceive(msg:EventMessage)
メソッドは、メッセージの種類に基づいて適切な受信メソッドを呼び出す単なる switch ステートメントです。
ゲームは開発中のため、エンティティとメッセージ (およびどのエンティティがどのメッセージに応答するか) のリストは流動的です。理想的には、ゲーム エンティティが新しいメッセージ タイプを受信できるようにしたい場合は、応答のロジックをコーディングできるようにしたいだけで、それを行うのではなく、他の場所で match ステートメントを更新する必要があります。
私が持っていた 1 つの考えは、Game エンティティ階層から receive メソッドを取り出して、def receive(e:EnemyShip,m:ExplosionMessage)
および defのような一連の関数を持たせることでしたが、これは、メッセージとゲーム エンティティ タイプreceive(e:SpaceStation,m:ExplosionMessage)
の両方をカバーするための match ステートメントが必要になるため、問題を悪化させます。
これは、 DoubleおよびMultipleディスパッチの概念と、おそらく Visitor パターンに関連しているように見えますが、頭を悩ませているところがあります。OOP ソリューション自体を探しているわけではありませんが、可能であればリフレクションを避けたいと考えています。
編集
さらに調査を行って、私が探しているのは Clojure のようなものだと思いますdefmulti
。
次のようなことができます:
java - 欠点のない Visitor をエミュレートする設計
多くの欠点がなく、ビジター機能をエミュレートするためのクリーンなデザインを探しています。Java では、従来の実装 (GoF で説明されているように) は、if-else を取り除くために二重ディスパッチに頼っています。これを解決するために、リフレクションを使用して「Visitable」クラスの変更を回避する実装を見てきましたが、これらはメソッド名を探すときにハードコードされた文字列に依存しています。非常に便利ですが、それでもきれいなデザインではないと思います。
データ構造や優れた OO 設計を使用して同じアイデアをエミュレートすることは可能ですか? パターンである必要はありません。同様の問題が解決される例を探しているだけです (例: a を使用Map<Class<T>,SomeFunctionObject>
)。
更新次のようなもの:
実際には、テンプレート パターンとコマンド パターンが混在していると思います。それを強化する方法についての提案を自由に投稿してください。
architecture - (ネスト?)多重ディスパッチ[ビジターパターン]
アプリケーションアーキテクチャの障害になりました。ビジターパターンを使用して、実行時にわからないタイプの抽象オブジェクトに対して特定のアルゴリズムを実行し始めました。私の問題は、私のアルゴリズムがネストされた抽象型の型にも依存していることです。
私が何を意味するかを説明しましょう:
抽象DataSourceクラスがあります。これから、concereteDataSourceReferenceクラスとDataSourceExplicitクラスを実装します。また、抽象Reportクラス(逆シリアル化されたメタデータ)があり、そこから具体的なReportクラスReportTypeAおよびReportTypeBを実装します。これらのオブジェクトが作成されるとき、それらのDataSourceは任意の拡張DataSourceクラスである可能性があります。
それに応じて実行できるように、実際のレポートタイプとデータソースタイプの両方が必要です。ビジターパターンを使用してコンサートレポートタイプを取得できますが、後でDataSourceに対して同じことを行う方法がわかりません。
レポートにアクセスした後、データソースにアクセスできません。具体的なタイプのレポートを失うためです(基本のレポートタイプを受け入れる必要があるため:Accept(SomeDataSourceVisitor d、MetaReport m)-またはすべての可能なレポートタイプに対してオーバーロードします、これはビジターパターンの目的を無効にします。私の問題を参照してください。
何か案は?ディスパッチャ(訪問者)が新しいレポートをサポートしていることを確認するために新しいレポートタイプの開発者を必要としないため、動的な使用は避けたいと思います。
現在のコード:
c# - 二重発送と代替品
if
さまざまなタイプのクラスを処理するために、いくつかの成長する構造を処理するより良い方法を見つけようとしています。これらのクラスは、最終的には、いくつかの追加の状態情報を持つ、異なる値の型 (int、DateTime など) のラッパーです。したがって、これらのクラスの主な違いは、含まれるデータのタイプです。これらはジェネリック インターフェイスを実装していますが、同種のコレクションに保持する必要があるため、非ジェネリック インターフェイスも実装しています。クラス インスタンスは、それらが表すデータのタイプに従って処理され、その伝播はそれに基づいて継続または継続されません。
これは必ずしも .NET または C# の問題ではありませんが、私のコードは C# です。
クラスの例:
私は2つのオプションを考え出しました:
ダブルディスパッチ
私は最近、訪問者パターンと、そのようなケースを処理するための二重ディスパッチの使用について学びました。望ましくないデータが伝播されないようにするため、これは魅力的です (int のみを処理したい場合は、DateTime とは異なる方法で処理できます)。また、さまざまなタイプの処理方法の動作は、ディスパッチを処理する単一のクラスに限定されます。ただし、新しい値の型をサポートする必要がある場合は、かなりのメンテナンスが必要です。
ユニオンクラス
サポートされている各値型のプロパティを含むクラスは、これらの各クラスが格納するものになる可能性があります。値に対する操作は、適切なコンポーネントに影響します。これは、ダブル ディスパッチ戦略よりも複雑ではなく、メンテナンスも少なくて済みますが、「私はそのデータ型を操作しない」という行に沿って区別できなくなるため、すべてのデータが不必要に伝播することを意味します。 "。ただし、新しい型をサポートする必要がある場合は、このクラスに入れるだけで済みます (さらに、新しいデータ型をサポートするために作成する必要がある追加のクラスはすべて)。
より良いオプションはありますか?これら 2 つのオプションのいずれかに、私がすべきだとは考えていなかった何かがありますか?
design-patterns - ビジターパターンとダブルディスパッチの違い
ビジターパターンについて読んでいますが、ダブルディスパッチと同じように見えます。2つの間に違いはありますか?2つの用語を実行することは同じことを意味します。