2
我想修改我对树状结构和不同节点类型的访问者模式的用法。在树结构中的每个节点必须实现一个回调方法和游客实现必须实现类似的每个节点类型(他有兴趣的类型或至少)以下内容:树状结构中的访问者模式
/**
* 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
是非常危险的,因为每个节点允许的修改t ype应该只能在特定的写事务中实现(实现为提供遍历树结构的方法的游标)。否则,更改在commit()
期间不可见并且不会持续。
有关如何规避这种情况的任何建议?我莫名其妙地怀疑我能提供访问者接口方法签名肯定有不同...
好吧,我会提供不可改变的“包装”或代理类:
/** 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);
}
您可以让游标类使用代理来包装您的节点,这将向访问者公开与节点相同的接口。然后没有访客可以直接修改节点。事务逻辑可以放在代理中,或者代理委托给光标。 – nansen
例如,为每个需要其构造函数中的可修改实例的节点类型提供不可变的“包装器”或代理?好主意:-) – Johannes
@nansen,小心将该评论转换为答案? – MvG