2015-06-12 46 views
0

想象下面的場景。所有T類型的對象都是可複製的。有些包裝對象可能包含許多T類型的對象或任何擴展類T的引用。現在所有對象都被包含在一個狀態中,並且當任何包裝對象被用來修改所述狀態時,狀態被預先複製。問題在於,包裝對象指向原始狀態對象而不是處於複製狀態的對象,因此對包裝對象中包含的對象進行任何修改都會修改原始狀態而不是複製狀態。包裝對象中的不可變對象引用

有沒有簡單的方法可以解決這個問題?

例子:

class A extends T { 
    private int value; 

    public A(int value) { 
    this.value = value; 
    } 

    public int getValue() { 
    return value; 
    } 

    public void setValue(int toSet) { 
    this.value = toSet; 
    } 

    @Override 
    public A copy() { 
    return A(this.value); //Imagine deep-copy stuff here 
    } 
} 

現在想象一個State有那些A的列表:

class Modification { 
    A toModify; 
    int toSet; 
} 

class State { 
    List<A> objs = ...; // Some A's 
    private State(State otherState) { 
     //Deep-copy is done here... 
     //Copy all A's that are contained in this state too 
    } 

    public State applyAModification(Modification mod) { 
      State copy = new State(this); 
      //now I want to modify the A that was referenced in mod 
      //not the original, but the copy in the copied state 
      return copy; 
    } 
} 

更新:可能有人點我到一個方向或點上一些關鍵字,我可以搜索?這個問題似乎非常具體,但即使在試圖解決這個問題好幾個小時之後,似乎也沒有真正的解決辦法。

編輯:對不起,所有的錯別字,咄

+1

進行深層複製? – assylias

+0

您能否提供一個簡潔的工作程序來說明您的擔憂?僅使用文本很難理解和可視化概念。 – sstan

+0

對象已被深度複製,但包裝對象中的引用仍然指向原始數據,因爲它們是針對特定狀態中的對象構建的。這意味着複製一個狀態會使原始狀態的所有相應的包裝對象不適用於該副本。 – naze

回答

0

一個可行的辦法是維持A級版本或任何子類裏面,而不是從外部創建副本。例如:

class A extends T { 
    List<A> versions = new ArrayList(); 
    private int value; 

    public void setValue(int value) { 
     versions.add(createCopy()); 
     this.value = value; 
    } 

    public A createCopy() { 
     return deepCopycopyOfA; 
    } 
} 

所以你仍然處理王氏只有1參考A. 年底還將封裝在各自的班級內的每個突變創建副本的複雜性。

+0

這會佔用多餘的內存,因爲管理何時從列表中刪除引用不是微不足道的,識別正確的A似乎也很困難。 – naze