0

ビジターパターンについての本を読みました。oodesign の Web サイトと同じクラス図が表示されます。

新しい ConcreteElement クラスを追加するのは難しいと言われています。しかし、私はその理由を理解していませんでした。私が理解したように、Concretevisitor は、concreteElement で使用する必要がある一連の操作を定義します。したがって、前に定義したのと同じ操作を持つ新しい要素を追加する場合、何も追加する必要はありません (ConcreteElement 自体のみ)。以前にビジターで定義したのと同じ操作を持たない新しい要素を追加する場合は、新しいビジターを追加する必要があります。しかし、これはどのデザイン パターンでも行う必要があります。

4

4 に答える 4

3

さて、すべての訪問者を拡張する必要があります。

呼び出し元、訪問する必要があるいくつかの要素、および個々の要素の処理を行う要素 (訪問者) があります。あなたの目標は、要素の実装と呼び出し元を固定し、新しい訪問者によって機能を拡張することです。

通常、具体的な訪問者がたくさんいます。処理する新しいタイプの要素を追加する場合は、これを考慮してすべての具体的な訪問者を変更する必要があります。

なんで?

呼び出し元が "Factory" で、"Car" と "Bike" という要素があるとします。

操作「ペイント」には、メソッドが必要です

void process(Car c); // Paint a car
void process(Bike b); // Paint a bike

「組み立てる」「梱包する」「洗う」などの作業も同様です。

要素「Scooter」を追加すると、すべての操作を新しいメソッドで拡張する必要があります

void process(Scooter s); // Handle a Scooter

これはちょっとした作業です。また、追加する要素が他の要素と大きく異なり、操作に簡単に適合させることができないという問題に遭遇することもあります。

ウィキペディア (http://en.wikipedia.org/wiki/Visitor_pattern) によると

本質的に、ビジターを使用すると、クラス自体を変更することなく、クラスのファミリーに新しい仮想関数を追加できます。代わりに、仮想関数の適切な特殊化をすべて実装するビジター クラスを作成します。ビジターはインスタンス参照を入力として受け取り、二重ディスパッチによって目標を実装します。

これは、私が上で言おうとしていることをかなり抽象的な言い方で表現したものです。通常、これらのメソッドを要素に追加しますが、それができない場合は、メソッドを別のものに追加し、それを渡して処理を行う必要があります。これは少し余分な作業ですが、状況に応じて行う価値があるかもしれません。

于 2012-06-28T11:12:32.827 に答える
1

新しい具象要素を追加する場合、すべての訪問者クラスはvisit、新しい要素の新しいメソッドを追加する必要があります。訪問者を使用しなかった場合は、とにかく新しい具象要素に同等のメソッドを追加する必要があります。

ただし、各訪問者に新しいメソッドを追加することは、同等のメソッドのセットを新しい要素クラスに追加するよりも難しい場合があります。その理由は、訪問者は要素ツリー構造をトラバースする必要があり、そのように独自の状態データを管理する必要がある場合があるためです。新しいメソッドを追加するには、その状態データを変更する必要があります。これには、新しいメソッドが他の要素のvisit既存のメソッドとどのように相互作用するかを考える必要があります。visit

訪問者がいない場合は、よりまとまりのある新しい具象要素の内部状態についてのみ心配する必要があるため、新しい要素クラスに同等のメソッドを追加する方が簡単な場合があります。

于 2012-06-28T12:27:45.407 に答える
1

これは、最近SOの質問に出てきました。この質問、より具体的には議論から私自身を引用するには

一連のエンティティ (アクセスするクラス) を変更しないという前提条件は、各具体的な訪問者に新しい VisitXYZ を実装する必要があるためです。しかし、永続化ビジター、テキスト検索ビジター、印刷ビジター、検証ビジターをサポートしていて、新しいエンティティーを追加して、それらすべてを実装したい場合は、その理由について十分に検討したことはありません。とにかく機能性。ビジター パターン (共通の基本クラスを使用) を使用すると、コンパイラは、実装するのを忘れたものを見つけることができます。

そうです、追加の具体的な要素 (またはエンティティ) を実装するのは難しいとよく言われますが、私の意見では、それはごちゃごちゃです。

于 2012-06-28T12:13:14.537 に答える
1

基本的に、訪問者パターンは一種のデータ操作者であり、

  • いくつかのルールに従って要素間をトラバースする
  • これらの要素が提供するデータを使用して計算と操作を行います

一言で言えば、ビジター パターンは、要素クラスの定義に触れることなく、システムの機能を拡張します。

しかし、これは、新しい具象要素クラスが追加された場合、ビジター クラスを修正する必要があるということですか? それは、訪問者パターンがどのように設計および実装されるかにかかっていると思います。

訪問者のすべての訪問メソッドを訪問ファンクターに分離し、それらを動的に結合すると、訪問者と訪問者の両方に対して、how システムを拡張するときに簡単になる可能性があります。

これは私が数年前に書いた訪問者パターンの実装です。コードは少し古く、洗練されていませんが、何とか動作します :)

https://github.com/tezheng/visitor

于 2012-07-01T07:11:07.890 に答える