4

次のクラス図 (ビジター パターンの実装) があります。

ここに画像の説明を入力

期待される結果:
1) WiredVisitor は Router と WiredNetworkCard のみにアクセスする必要があります
2) WirelessVisitor は Router と WirelessNetworkCard のみにアクセスする必要があります

ですから、私の質問は次のとおりです。期待される結果を達成するために、設計 (またはコード) をどのように変更すればよいでしょうか?

PS 私の現在の解決策は、両方の訪問者の各 visit(card:INetworkCard) メソッドに次のコードを追加することです。

// in WiredVisitor
if (card.getClass.equals(WiredNetworkCard.class)){
    // do logic of visit method
}

// in WirelessVisitor
if (card.getClass.equals(WirelessNetworkCard.class)){
    // do logic of visit method
}
4

4 に答える 4

3

非循環的な訪問者パターンの精神で、訪問者をサブクラス固有のものに分けます。型チェックは引き続き必要ですが、アクセスされている型に含まれていることに注意してください。

訪問者インターフェースは次のとおりです。

interface IVisitor {
}

interface IRouterVisitor extends IVisitor {
  void visit(Router router);
}

interface INetworkCardVisitor extends IVisitor {
}

interface IWirelessNetworkCardVisitor extends INetworkCardVisitor {
  void visit(WirelessNetworkCard card);
}

interface IWiredNetworkCardVisitor extends INetworkCardVisitor {
  void visit(WiredNetworkCard card);
}

具体的な訪問者は次のようになります。

class WiredVisitor implements IWiredNetworkCardVisitor, IRouterVisitor  {
  // ...
}

class WirelessVisitor implements IWirelessNetworkCardVisitor, IRouterVisitor {
  // ...
}

訪問したオブジェクト:

interface INetworkElement {
  void accept(IVisitor visitor);
}

class Router implements INetworkElement {
  @Override
  public void accept(IVisitor visitor) {
    if (visitor instanceof IRouterVisitor) {
      ((IRouterVisitor)visitor).visit(this);
    }
  }
}

interface INetworkCard extends INetworkElement {}

class WiredNetworkCard implements INetworkCard {
  @Override
  public void accept(IVisitor visitor) {
    if (visitor instanceof IWiredNetworkCardVisitor) {
      ((IWiredNetworkCardVisitor)visitor).visit(this);
    }
  }
}

class WirelessNetworkCard implements INetworkCard {
  @Override
  public void accept(IVisitor visitor) {
    if (visitor instanceof IWirelessNetworkCardVisitor) {
      ((IWirelessNetworkCardVisitor)visitor).visit(this);
    }
  }
}

これらの型チェックでは、その場合に何をしたいかによって、型が予期されたものでない場合にエラーをスローすることもできます。

于 2012-07-11T17:14:00.330 に答える
0

たとえば、これを行うことができます:

public interface IVisitor<T extends INetworkCard> {
   public void visit( T card );
}

次に、訪問者を次のように定義します。

public class WiredVisitor implements IVisitor<WiredNetworkCard> {
...
}


public class WirelessVisitor implements IVisitor<WirelessNetworkCard> {
...
}

これは教科書的な解決策ではないかもしれませんが、非常にクリーンで非常に読みやすいものです。

于 2012-07-10T23:00:06.357 に答える