2012-10-01 75 views
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); 
} 
+1

您可以讓遊標類使用代理來包裝您的節點,這將向訪問者公開與節點相同的接口。然後沒有訪客可以直接修改節點。事務邏輯可以放在代理中,或者代理委託給光標。 – nansen

+0

例如,爲每個需要其構造函數中的可修改實例的節點類型提供不可變的「包裝器」或代理?好主意:-) – Johannes

+0

@nansen,小心將該評論轉換爲答案? – MvG

回答

2

你可以讓遊標類使用代理來包裝你的節點,這將向訪問者公開與節點相同的接口。然後沒有訪客可以直接修改節點。事務邏輯可以放在代理中,或者代理委託給光標。