Visitor Pattern solution: few visitors have same interface but should work with different objects

前端 未结 4 1017
梦毁少年i
梦毁少年i 2021-01-20 04:31

I have following class diagram (visitor pattern implementation):

Expected result:
1) WiredVisitor should visit only Router and WiredNetworkCard
2)

4条回答
  •  花落未央
    2021-01-20 05:05

    In the spirit of the acyclic visitor pattern, separate your visitors into subclass specific ones. Note that you'll still need the type check, but it's contained to the type being visited:

    Here are the visitor interfaces:

    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);
    }
    

    The concrete visitors will look like this:

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

    And the visited objects:

    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);
        }
      }
    }
    

    In those type checks, you can also throw an error if the type is not the expected one, depending on what you'd like to happen in that case.

提交回复
热议问题