問題タブ [visitor-pattern]
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.
java - オブジェクトに訪問者を使用するのはいつですか。
私はいつも、オブジェクトがそれに作用するためにデータとメッセージが必要だと思っていました。オブジェクトに外部的なメソッドが必要なのはいつですか。訪問者を迎えるには、どのような経験則に従いますか?これは、オブジェクトグラフを完全に制御できることを前提としています。
design-patterns - コマンドパターンとビジターパターン
ビジターがレシーバーの状態を変更できるようにすることは一般的に受け入れられますか、それとも代わりにコマンドパターンにする必要がありますか?
c++ - ビジターおよびテンプレート化された仮想メソッド
訪問者パターンの典型的な実装では、クラスは基本クラスのすべてのバリエーション (子孫) を考慮する必要があります。ビジター内の同じメソッド コンテンツが異なるメソッドに適用される場合が多数あります。この場合、テンプレート化された仮想メソッドが理想的ですが、現時点では許可されていません。
では、テンプレート化されたメソッドを使用して、親クラスの仮想メソッドを解決できますか?
与えられた(基礎):
基礎が築かれたので、キッカーの出番です (テンプレート化されたメソッド):
意図的に、メソッド宣言Visitor_Cout
にキーワードが含まれていません。virtual
メソッド シグネチャの他のすべての属性は、親の宣言 (または仕様) と一致します。
全体像として、この設計により、開発者は、ターゲット オブジェクト (訪問を受け取るオブジェクト) のタイプのみが異なる共通の訪問機能を実装できます。上記の実装は、派生ビジターの実装がオプションのメソッドを実装していない場合のアラートに対する私の提案です。
これは C++ 仕様で合法ですか?
(コンパイラXXXで動作すると言う人もいますが、これは一般的な言語に対する質問です。)
java - これらのクラスがビジター パターンとジェネリックを使用するように支援が必要
訪問者パターンを生成して実装するために助けが必要です。私たちは大量に使用しinstanceof
ていますが、それは苦痛です。変更できると確信していますが、それを行う方法がわかりません。
基本的に私たちはインターフェースを持っていますProcessData
ProcessDataGeneric
これで、実装するクラスができましたProcessData
ProcessData を取得する新しいインターフェイス
ProcessData を取得できるようにラッパーを実装する一般的な抽象クラスになりました
これで実装
同様に
これらのクラスを使用するときは、常に行う必要がありますinstanceof
これを行うためのより良い方法があることは知っていますが、ジェネリックとビジター パターンを利用する方法がわかりません。どんな助けでも大歓迎です。
アップデート
これらのクラスは、はるかに大きな実装の一部にすぎないことを付け加えておきます。ProcessData
andProcessDataGeneric
は、デリゲート (など) の外側にあるものですProcessDataMotorferdsel
。デリゲートはすべて拡張しProcessDataCommon
ます。
おそらくリファクタリングを行うのが最善であることに同意できますが、これは 2 年前の製品コードであり、リファクタリングにはコストがかかります (時間、テストなど)。しかし、私は喜んでそれを行います。
更新 #2
Generic プロセスを開始しようとしましたが、コンパイル エラーが発生します。これが今の様子です。
オンラインでコンパイルエラーが発生しますunwrapped = new ProcessDataGeneric<ProcessDataMotorferdsel>(this);
:
[javac] ProcessDataMotorferdsel.java:52: incompatible types
[javac] found : ProcessDataGeneric<ProcessDataMotorferdsel>
[javac] required: ProcessData<ProcessDataCommon>
[javac]
そのエラーメッセージの表も裏もわかりません。ProcessDataMotorferdsel クラスは ProcessDataCommon を拡張するため、IMO は機能するはずです。
c++ - 仮想テンプレート メンバーの回避策が必要
ビジター デザイン パターンを実装するプログラムを作成する必要があります。問題は、基本ビジター クラスがテンプレート クラスであることです。これは、BaseVisited::accept() がテンプレート クラスをパラメータとして取り、'this' を使用し、'this' がオブジェクトの正しい実行時インスタンスを指す必要があるため、仮想化する必要があることを意味します。
この問題を回避する方法があれば知りたいです。
java - Java 抽象ビジター - 成功することが保証されていますか? もしそうなら、なぜですか?
訪問者パターンを使用して、プロキシされたインスタンスの背後にあるランタイム クラスを把握しようとして、休止状態を扱っていました。そこで、あるアプローチを思いついたのAbstractVisitable
ですが、いつも正しい結果が得られるのだろうか。
次のコードを検討してください。
これにより、からメソッドConcreteVisitable
を継承するが作成されます。C++ では、 AbstractVisitableでは ではなくを参照する可能性があるため、これは危険であると考えます。特定の状況下でコードが出力されるのではないかと心配していました。しかし、上記のコードは を出力しますが、実際の型を動的プロキシの背後に隠しています (これは私が思いつくことができる最も困難なケースです)。上記の抽象的なビジター アプローチは動作することが保証されていますか、それともこのアプローチにはいくつかの落とし穴がありますか?accept
AbstractVisitable
this
AbstractVisitable::this
ConcreteVisitable::this
class AbstractVisible
class ConcreteVisitable
this
ポインタに関してJavaでどのような保証が与えられていますか?
c++ - リンゴ、オレンジ、および最も派生したc++クラスへのポインター
私がたくさんの果物を持っているとしましょう:
そして、上記の果物に作用するいくつかの多型関数:
OK、待ってください。すぐそこに止まります。この時点で、正気の人なら誰でもEat()をFruitクラスの仮想メンバー関数にすることに注意してください。しかし、私は正気の人ではないので、それは選択肢ではありません。また、フルーツクラスのヘッダーファイルにその農薬*を含めたくありません。
悲しいことに、次にできることは、メンバー関数と動的バインディングで可能なことです。
そして明らかに、ここでの問題は、Eat()に渡すポインターがApple*やOrange*ではなくFruit*になるため、何も食べられず、私たち全員が非常に空腹になることです。
だから私がこれの代わりに本当にやりたいこと:
これは:
しかし、私の限られた知識では、そのような魔法は存在しません。ただし、dynamic_castへの呼び出しでいっぱいの大きな厄介なifステートメントの形式を除いては。
それで、私が気付いていない実行時の魔法はありますか?または、dynamic_castsでいっぱいの大きな厄介なifステートメントを実装して維持する必要がありますか?それとも、私はそれを吸い上げて、Rubyでこれをどのように実装するかについて考えるのをやめ、少量の農薬が私の果物のヘッダーに入るのを許可する必要がありますか?
更新:裸のEat関数とPesticideを使った工夫の代わりに、意味がないのでEatを果物に入れたくないと仮定します。自分で食べる方法を知っている果物?Pshaw。代わりに、Eat関数を備えたEaterクラスが必要です。このクラスには、果物の種類ごとに異なるコードがあり、食べる人が認識できない果物の場合に備えて、デフォルトのコードがいくつかあります。
しかし、繰り返しになりますが、これは機能せず、C++での簡単な解決策はdynamic_castへの一連の呼び出しのようです。
ただし、回答の1つが示唆しているように、別の賢い解決策があるかもしれません。Fruitsが、MustPeel()やMustWash()などの関数を使用して、食べる人にとって重要な品質を公開した場合はどうなりますか?次に、単一のEat()関数でうまくいくことができます...
更新: Daniel Newbyは、Visitorを使用すると、提示された問題も解決されると指摘しています...しかし、これにはセマンティックな逆立ちが必要です(Fruit::useまたはFruit::beEaten?)。
私はいくつかの答えを受け入れたいと思いますが、psmearsの答えは実際には将来の読者にとって最良のものだと思います。みんな、ありがとう。
visitor-pattern - パラメータが不足している訪問者パターン
これは Visitor パターンの一般的な問題であるに違いないので、標準的な解決策があるかどうかを確認したいと思います。
メソッドがツリークラス自体に組み込まれているツリートラバーサルをどのように再コーディングできますか?
ビジターを使用するコードに。頭に浮かぶ2つの解決策は次のいずれかです
または、accept(Visitor&) および visit() メソッド自体に引数を追加します。しかし、これは、クラスに組み込まれた元のトラバーサルに勝るものはありません。
さらなる問題として、組み込みトラバーサル メソッドのそれぞれが異なる引数を取る場合、または一部の戻り値と他の戻り値がない場合、またはすべてが同じ型を返さない場合はどうなるでしょうか?
c++ - ビジターパターンがダウンキャストを回避する方法
ビジターパターンコードのダウンキャストを避けるために、誰でも前後にサンプルコードを表示できますか?
ありがとう。
c++ - シングルディスパッチとダブルディスパッチとは何ですか?
私はビジターパターンを次のように書きましたが、シングルディスパッチとダブルディスパッチが何であるかわかりません。AFAIK、シングルディスパッチは呼び出し元のタイプに基づいてメソッドを呼び出しますが、ダブルディスパッチは呼び出し元のタイプと引数のタイプに基づいてメソッドを呼び出します。
ダブルディスパッチはシングルクラス階層で発生すると思いますが、ビジタークラスに2つのクラス階層があるのに、それでもダブルディスパッチと見なされるのはなぜですか。
私が提供したサンプルコードを使用して説明してください。
AFAIK、最初のディスパッチはacceptを呼び出すオブジェクトで発生し、2番目のディスパッチはvisitメソッドを呼び出すオブジェクトで発生します。
ありがとう。