2015-06-12 48 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