問題タブ [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.

0 投票する
2 に答える
107 参照

java - パッケージ外で事前定義されたパッケージ メソッドを変更する方法は?

Animal 親クラスを含む「animal」というパッケージがあるとしましょう。Cat は Animal から拡張され、Dog は Animal から拡張されます。ただし、Animal は次のように設計されています。

Cat & Dog クラスは次の構造に従います。

それらのそれぞれには、次のようなメソッド、drinkWater() があります。

ここで私がやろうとしているのは、動物の「リンクされたリスト」を作成し、それぞれが順番に水を飲むことです。ただし、たとえば、猫が n 量の水を飲むと、n+1 量の水が猫に渡されます。

私の目的は、「元の動物のパッケージに触れるのではなく、水を飲む動作を 1 匹ずつ変える」という問題を解決するための解決策を見つけることです。私はクラスでその「有名な」素朴な解決策を持ってきました:

それから、私は研究を始めました。これは本当に迅速で汚い解決策に見えたからです。

そこで、「ビジターパターン」というデザインパターンを見つけました。さて、二重ディスパッチの問題を解決する非常にクールなパターンですが、私の側には問題があります: 訪問可能なインターフェース (accept() メソッドを宣言する) は、元の動物によって「実装」されなければなりません。しかし、私の目標は「元の動物のパッケージを変更するのではなく、飲料水の動作を変更する」ことです。私は何かが欠けていると確信しています。

では、ちょっとしたハックで、ビジター パターンがまだ機能すると思いますか、それとも別のパターン/ソリューションの方が優れていると思いますか? ありがとう。

0 投票する
3 に答える
1245 参照

c++ - 仮想メソッドなしのデザインパターン「コンテナビジター」?

私はアプリケーションの設計を開発しており、ある種のVisitor デザイン パターンを適用できると思っていましたが、それはまさに私が探しているものではないことが判明しました。この場合、誰かが私が必要とするバリアントを教えてくれるでしょうか?

私のコードの多くには、次のようなテンプレート引数「ContainerType」があります

現在、通常は多くのデータ フィールドを共有する「コンテナ」の数は少ないですが増え続けています。

Container1 と Container2 は、MyClass (およびその他) のテンプレート引数として使用されるようになりました。ここで、A、B、C はいくつかの定義済みクラスです。(get<A>(container)含まれているデータにアクセスするなどの方法があります。この設計により、必要な型を含むすべてのコンテナー型で MyClass を使用できるというコンパイル時の安全性が提供されます。)

ここで、「コンテナに特定のタイプ (例: A) が含まれている場合は何かを実行し、それ以外の場合は何もしない」という機能を追加したいと考えています。

これは、訪問者のように見えるもので行うことができます (ただし、仮想メソッドは使用されないことに注意してください)。「コンテナに A が含まれている場合はこれを行い、D が含まれている場合は別のことを行い、そうでない場合は何もしない」こともできます。これは

これは私が望んでいたことですが、ここに示す実装では、すべての ContainerType に対して受け入れを実装する必要があるため、より良い方法を探しています。誰かがacceptメソッドから派生しContainer1ContainerBase<D>のに展開するのを忘れた場合、事態は悪化します。さらに悪いことに、const バージョンと非 const バージョンの accept が必要になり、一部のコンテナーには 5 つ以上の型が含まれているため、見た目も良くありません。

すべてのコンテナ クラスは複数回の継承によって構築されているContainerBase<T>ため、この構造を使用して、ContainerBase クラスに accept (および accept(..) const) を実装できないか考えてみました。私はすでに Lokis のタイプリストを見てきましたが、ここでそれらを使用する方法がわかりません。何か考えはありますか?

それとも、訪問者のような構造なしでこれを行うことは可能ですか?

どうもありがとう!

編集:RTTIを使用できることはわかっていますが、可能であればランタイムチェックと仮想メソッドを避けたいです。

0 投票する
2 に答える
82 参照

user-interface - 正しい順序でのブリッティング - 訪問者の問題

シンプルなGUIを設計しています。私は子と 1 つの親を持つウィジェットを持っています。各 Widget は、WidgetComposite オブジェクトのベクトルを持つ Composite オブジェクトです。これらの WidgetComposites の 1 つは PaintingBehaviour ですが、Widget はそれ自体を認識していません。

ウィンドウを表示するには、ScreenVisitor と呼ばれるビジターを使用します。Visitor が呼び出されると、次のようになります。

最初のウィジェットである WidgetScene は、各ウィジェットで反復処理を行い、「accept(Visitor* v)」メソッドを呼び出します。次に、各ウィジェットが訪問者を受け入れ、その子に対して繰り返し処理を行います。

たとえば、これは訪問者が受け入れなければならないオブジェクトのリストです (発生する順序で)。

今、私の問題は簡単です: 各ウィジェットをその親にペイントしたいのです。どのように進めますか?ツリーで試してみましたが、常に同じ問題があります。階層を上に移動する必要がある場合 (たとえば、child3 を表示した後、child4 を表示する必要がある場合)、取得方法がわかりません。右の親。

私は C++ でコーディングしていますが、この問題は言語固有ではありません。

あなたはなにか考えはありますか ?前もって感謝します !

0 投票する
3 に答える
4762 参照

java - Javaでの一般的なビジターパターン

ジェネリックを使用したビジターパターンの次のJava実装は、有用であるほど一般的ですか?(そうだと思います)。

何らかの方法で改善できますか?匿名クラスを使用して簡単に呼び出し可能であることが重要です。ありがとう。

(使用例):

定義:

0 投票する
1 に答える
207 参照

java - PropertyChangeSupport による Swing GUI の更新に関する設計上の質問

過去に、特定のフィールドを表示する Swing 要素を更新するために PCS を使用しましたが、すべてが期待どおりに機能しました。しかし、私は現在、多くのフィールドを表示する比較的複雑な (つまり、ひどく設計された) UI に直面しています。データの更新は束になって (約 1,000 フィールドの新しい値を含むネットワーク パケット)、このようなものを処理する適切な方法は何か疑問に思っていました。

私の主な懸念は、データ パケットが来るたびに 1,000 の PropertyChangeEvents がトリガーされ、1,000 の .repaint() (または .revalidate() など) が発生することです。より賢明な方法は、「gui.stopRepainting(); fireAllThePropertyEvents(); gui.restartPainting();」のようなことをするように見えました。それを行う方法はありますか、またはこれを処理するためのより良い方法はありますか?

0 投票する
5 に答える
4004 参照

design-patterns - 訪問者パターンのバリエーション: 2 番目のディスパッチを訪問者の `Visit` メソッドに移動してみませんか?

はじめに

どうやら、私はプログラマーとしての人生全体で、「型にはまらない」ビジター パターンを実行してきたようです。

はい、Visitor のメソッドから具体的な複合要素の Visit メソッドにディスパッチしVisitます。

これが私が学んだ方法だと思いますが、今ではその例を見つけることができず、学んだソースがなくなりました。

さて、具体的な要素のディスパッチが複合要素のAcceptメソッドに組み込まれているという圧倒的な証拠に直面して、私が行ってきた方法に少なくとも何らかの利点があるかどうか疑問に思っています。私に見える2つの利点は次のとおりです。

  1. ディスパッチ方法を決定する場所は 1 か所しかありません。ベース ビジターです。
  2. 新しい複合要素タイプを追加して、基本ビジターにそれらを無視させることができますが、派生ビジターはVisitそれらを処理するためにオーバーライドできます。

基本的なコンポジット/ビジター モデルは次のとおりです。

訪問者クラスは、正規バージョンではなく、2 番目の型ベースのディスパッチを担当するようになったことに注意してください。たとえば、次のFooようになります。

さて、ディフェンスですが…

メリット1

新しい CompositeElement タイプを追加したいとしましょう:

ビジター モデルでこの新しい要素タイプに対応するには、BaseVisitor クラスに変更を加えるだけです。

if確かに、これは小さな問題ですが、メンテナンスが簡単になるようです (つまり、大きな問題やswitchステートメントを気にしない場合)。

メリット2

コンポジットを別のパッケージで拡張したいとしましょう。を変更せずにこれに対応できますBaseVisitor

この構造を持つことで、拡張された CompositeElement 型に対応するためにBaseVisitor必要な依存関係を断ち切ることができます。VisitExtended

結論

現時点では、Visitor パターンを十分に実装していないか、十分に長く維持していないため、不利な点が私に重くのしかかっています。明らかに、大きな switch ステートメントを維持するのは苦痛であり、パフォーマンスへの影響もありますが、BaseVisitor拡張機能に依存しないようにする柔軟性を上回るかどうかはわかりません。

マイナス面については、あなたの考えを考慮してください。

0 投票する
5 に答える
2895 参照

c++ - C ++:ビジターパターンに関する疑問

私はビジターパターンとは何か、そしてそれをどのように使うかを知っています。この質問はこれと重複していませ


自分が書いた再利用可能なコードのほとんどを配置し、ほとんどのプロジェクトにリンクするライブラリがあります。

多くの場合、一部のクラスに機能を追加する必要がありますが、これらの新しい機能をライブラリに追加する必要はありません。実際の例を使用しましょう:

このライブラリには、、、およびによって継承されたクラスがありShapeます。CircleShapePolygonShapeCompositeShape

私は現在、これらをレンダリングする必要があるグラフィカルアプリケーションを開発していますが、使用するプロジェクトの一部はレンダリングを行わず、他のグラフィカルプロジェクトは使用する可能性があるため、コアクラスにShape仮想関数を配置したくありませんさまざまなレンダリングエンジン(このプロジェクトではQtを使用していますが、ゲームではOpenGLを使用するため、関数にはさまざまな実装が必要になります)。renderShapeShaperender

もちろん、これを行う最も有名な方法は、Visitor Patternを使用することですが、これは私の心にいくつかの疑問を投げかけます。

私のように、どのライブラリのどのクラスも拡張する必要がありますShape。ほとんどの公共図書館(それらのすべてについて)は、VisitorPatternをサポートしていません。なぜ?どして私がこんな事に?

ビジターパターンは、C++でダブルディスパッチをシミュレートする方法です。applyVisitorこれはC++でネイティブではなく、明示的に実装する必要があるため、クラスインターフェイスがより複雑になります。関数をクラスの関数と同じレベルにする必要はないと思います。これは抽象化を破るようなものです。

明示的にアップキャストShapeするdynamic_cast方が費用がかかりますが、私にはそれはよりクリーンなソリューションのように見えます。


だから、私は何をすべきですか?すべてのライブラリクラスにダブルディスパッチを実装しますか?提供しているライブラリが私のものShapeではなく、インターネット上にあるGPLライブラリが見つかった場合はどうなりますか?

0 投票する
1 に答える
1160 参照

java - JavaでDAG構造のイテレータラッパーを作成するには?

データ構造に対してイテレータが必要です。今のところ、データ構造が何であるかはわかりません.DAG(有向非巡回グラフ)かもしれませんが、連結リストかもしれません。だから私はそれをイテレータにラップしたいのですが、今は特定のデータ構造では考えていません。

再帰的なビジターで DAG を訪問する方法は知っていますが、反復子メソッドnext()hasNext().

イテレーター内で、現在のノード インスタンスを作成し、すべての子に対して for ループを繰り返してから、親に戻ります。「既に訪問済み」フラグが必要です。だから私DagElementはこれらのより多くの属性を持っています:

これはきれいな解決策ではないと思います。

何かアドバイス?

0 投票する
2 に答える
4932 参照

design-patterns - ストラテジー、ビジター、テンプレート メソッドのパターンの違いは何ですか?

私は、これらの設計パターンについて学んだばかりのクラスにいます。しかし、それらの間に違いは見られませんでした。それらは同じように聞こえ、抽象的なクラスの上に具体的なクラスを作成します。誰かがこの疑いを消すのを手伝ってくれませんか? ありがとう (:

0 投票する
3 に答える
439 参照

java - ビジターのデザインパターンを説明する優れた記事を誰か教えてくれませんか

コードが Java で記述されていれば、ビジターのデザイン パターンを説明する優れた記事を教えてもらえますか。

ありがとう