2

来客パターンについて質問です!データ構造 Class があり、その中に Class2 との has-a 関係があるとします。Class2 には、約 10 クラスの特定のクラス階層があります。

Class1 インスタンスのリストを反復処理し、Class2 のタイプに従って Visitor.visit(Class1) のリクエストをディスパッチする必要があります。class1 コンテキストからの変数が必要なため、class2 で反復を使用できません。

今、私は Class1 オブジェクトを受け入れるディスパッチャについて何か考えています。このクラスに基づいて、class2 のタイプをチェックし、何かを呼び出します。

ビジター.visitClass2Type1(クラス1オブジェクト)

しかし、この場合、訪問者パターンの同じ署名を失います...

もう 1 つの質問は、ビジター パターンのコンテキストで変数を挿入するにはどうすればよいかということです。ツリー構造をたどる場合のように、前のレベルの親変数を保持して、下位レベルで何かを実行したいと考えています。

4

3 に答える 3

4

次のオブジェクトを解釈する必要があるコンテキストを Visitor に伝える setContext() メソッドを Visitor クラスに追加できます。

複数のレベルでネストされたオブジェクト関係がある場合、アナログの leaveContext() メソッドを追加して、ビジター クラスにコンテキストのスタックを保持できます。

于 2012-08-29T14:55:47.367 に答える
2

フィリップが提案したことを一歩進めて、これを試してください。

指定されたクラス Widget が親であり、クラス Feature が子階層の基本型です

簡単な使い方:

// widget will have an instance of a Feature subclass from args or config, etc
Widget theWidget = new Widget(args);

// create and configure visitor
Visitor theVisitor = new Visitor();
theVisitor.prop1 = x; 
theVisitor.prop2 = y;
theVisitor.prop3 = z;

theWidget.visit(theVisitor);

ウィジェット (親クラス):

class Widget 
{
   Feature _childFeature;

   void visit(Visitor visitor)
   {
      visitor.beginAccept(this);
      childFeature.visit(visitor);            
      visitor.endAccept();
   }

}

フィーチャ クラスの階層:

abstract class Feature
{
   abstract void visit(Visitor visitor);
}

class Sunroof extends Feature
{
   void visit(Visitor visitor)
   {
      visitor.accept(this);
   }
}

class BulletProof extends Feature
{
   void visit(Visitor visitor)
   {
      visitor.accept(this);
   }
}

class GoldPlated extends Feature
{
   void visit(Visitor visitor)
   {
      visitor.accept(this);
   }
}

親と子の両方を使用する具体的なビジター:

class ExampleVisitor extends Visitor
{

   private _widgetInProcess;


   void beginAccept(Widget w)
   {
      _widgetInProcess = w;
   }

   void accept(Sunroof feature)
   {
      // do work based on both _widgetInProcess and type-specific feature
   }

   void accept(BulletProof feature)
   {
      // do work based on both _widgetInProcess and type-specific feature
   }

   void accept(GoldPlated feature)
   {
      // do work based on both _widgetInProcess and type-specific feature
   }

   void endAccept()
   {
      _widgetInProcess = null;
   }

}

beginAcceptスタックにプッシュすると、さまざまなacceptメソッドがスタックをピークして親コンテキストを取得し、スタックendAcceptからポップするツリー モデルのユースケースも視覚化できます。これにより、常に親チェーンにアクセスしながら、ツリーを再帰的に処理できます。

于 2012-08-30T13:13:43.323 に答える
2

あなたの Visitor.visit メソッドは Visitor.visit(Class2, Class1) のようにすべきだと思います。ここで、ビジター クラスは Class2 の各タイプの visit メソッドを実装します。

したがって、visit(Class2-1, Class1)、visit(Class2-2,Class1)...visit(Class2-10,Class1) を実装できます。

このようにして、visit メソッド内の Class1 オブジェクト情報にアクセスできるようになると思います。visit メソッドの呼び出しは動的に決定されるため、Class2 リストが何を持っているかは問題ではありません...

詳細については、wiki ページを参照してください: http://en.wikipedia.org/wiki/Visitor_pattern

于 2012-08-29T15:16:11.567 に答える