我想修改我对树结构和不同节点类型的访问者模式的使用。树结构中的每个节点都必须实现一个回调方法,并且访问者实现必须为每个节点类型(或者至少是他感兴趣的类型)实现类似以下的内容:
/**
* 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
是非常危险的,因为每个节点类型允许的修改应该只能在特定的写入事务中进行(实现为提供遍历树结构的方法)。否则,更改在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);
}