これは、Visitorパターンの優れたリファレンスであり、次のように言及されています。
プログラムでaccept()メソッドが呼び出されると、その実装は次の両方に基づいて選択されます。
関連するvisit()メソッドが呼び出されると、その実装は次の両方に基づいて選択されます。
- 訪問者の動的タイプ。
- accept()メソッドの実装内から認識される要素の静的タイプ。これは、要素の動的タイプと同じです。(ボーナスとして、訪問者が指定された要素の型の引数を処理できない場合、コンパイラーはエラーをキャッチします。)
したがって、visit()メソッドの実装は、次の両方に基づいて選択されます。
それから彼らは次のことに言及し続けます:
これにより、ダブルディスパッチが効果的に実装されます...
このように、要素のグラフをトラバースするための単一のアルゴリズムを記述でき、要素と訪問者。
これは、Java車の例で見ることができます。
class Car implements CarElement {
CarElement[] elements;
// ...
public void accept(CarElementVisitor visitor) {
for(CarElement elem : elements) {
elem.accept(visitor);
}
visitor.visit(this);
}
}
したがって、要約すると、あなたの例では、元のDP実装から多くのメリットを得ることができませんが、例がより複雑な場合、たとえば、 Elementのいくつかの内部実装を持つコンポジット(上記のJava車の例のように)、訪問者の行動をその内部要素の一部またはすべてに適用できます。
元の質問へのコメントに基づいて、このパターンには2つの部分があります。
- パターンの本来の動機は、オブジェクトの複雑な構造にアクセスし、アクセスするクラスインターフェイスを変更せずにオブジェクトに対して操作を実行することです。
- パターンの実装方法:これは、おっしゃるようにダブルディスパッチを使用した場合です。
次のデザインパターンブックを強くお勧めします。これは、多くの概念を実際に単純化するためです。GoFの本は時々あまりにも学術的です。
ヘッドファーストデザインパターン
この本によると、ビジターを使用することの長所と短所は次のとおりです。
(使用例のコンテキストで)
長所
- 構造自体を変更せずに、複合構造に操作を追加できます
- 新しい操作の追加は比較的簡単です
- ビジターが実行する操作のコードは一元化されています
短所
- 複合クラスのカプセル化は、Visitorが使用されると壊れます。
- トラバーサル機能が関係しているため、複合構造への変更はより困難です