title: Visitor pattern in tree-structures
body: <p>I want to revise my usage of the visitor pattern for tree-structures and different node types. Every node in the tree-structure has to implement a callback method and the visitor implementation must implement something like the following for each node type (or at least the types he's interested in):</p>
  
  <pre><code>/**
   * Do something when visiting a {@link CommentNode}.
   * 
   * @param pNode
   *          the {@link CommentNode}
   */
  EVisitResult visit(final @Nonnull CommentNode pNode);
  
  /**
   * Do something when visiting an {@link ElementNode}.
   * 
   * @param pNode
   *          the {@link ElementNode}
   */
  EVisitResult visit(final @Nonnull ElementNode pNode);
  </code></pre>
  
  <p>I'm using transactional cursor semantics to navigate through the tree-structure and provide an acceptVisitor-method, that is in the cursor I've implemented the following:</p>
  
  <pre><code>@Override
  public EVisitResult acceptVisitor(final @Nonnull IVisitor pVisitor) {
    assertNotClosed();
    return mCurrentNode.acceptVisitor(pVisitor);
  }
  </code></pre>
  
  <p>However the visitor is a flaw in the API, because exposing the nodes itself, for instance <code>ElementNode</code> is very dangerous, because modifications which are allowed for every node-type should only be able from within a specific write-transaction (implemented as a cursor which provides methods to traverse a tree-structure). Otherwise the changes are not visible and not made persistent during a <code>commit()</code>.</p>
  
  <p>Any suggestions on how to circumvent this situation? I somehow doubt I'm able to provide the visitor-interface as method signatures for sure have to be different...</p>
  
  <p>Ok, I will provide Immutable "wrapper" or proxy classes:</p>
  
  <pre><code>/** Mutable {@link CommentNode}. */
  private final CommentNode mNode;
  
  /**
   * Constructor.
   * 
   * @param pNode
   *          mutable {@link CommentNode}
   */
  private ImmutableComment(final @Nonnull CommentNode pNode) {
    mNode = checkNotNull(pNode);
  }
  
  /**
   * Get an immutable comment
   * 
   * @param pNode
   *          the {@link CommentNode} which should be immutable
   * @return an immutable instance
   */
  public static ImmutableComment of(final @Nonnull CommentNode pNode) {
    return new ImmutableComment(pNode);
  }
  </code></pre>