我想修改我对树结构和不同节点类型的访问者模式的使用。树结构中的每个节点都必须实现一个回调方法,并且访问者实现必须为每个节点类型(或至少他感兴趣的类型)实现类似下面的内容:
/**
* 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);
我使用事务性游标语义来浏览树结构并提供一个acceptVisitor方法,在游标中我实现了以下内容:
@Override
public EVisitResult acceptVisitor(final @Nonnull IVisitor pVisitor) {
assertNotClosed();
return mCurrentNode.acceptVisitor(pVisitor);
}
然而,访问者是API中的一个缺陷,因为暴露节点本身,例如ElementNode
是非常危险的,因为每个节点类型允许的修改只能在特定的写入内部进行 - transaction(作为游标实现,提供遍历树结构的方法)。否则,更改将不可见,并且在commit()
期间不会持久。
有关如何规避这种情况的任何建议?我不知何故怀疑我能够提供访客界面作为方法签名肯定必须是不同的......
好的,我将提供Immutable" wrapper"或代理类:
/** 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);
}
答案 0 :(得分:2)
您可以让游标类使用代理包装您的节点,这将向访问者显示与节点相同的接口。然后没有访问者可以直接修改节点。事务逻辑可以放在代理中,或代理委托回光标。