Immutable objects reference in wrapper-objects

197 Views Asked by At

Imagine the following scenario. All objects of type T are copyable. There are wrapper-objects that may contain references to many objects of type T or any extending class of T. Now all objects are contained in a state, and when any wrapper-object is used to modify said state, the state is copied beforehand. The problem is that the wrapper-objects point to the original states objects instead of the objects in the copied state thus making any modifications in regards to the objects contained in the wrapper-objects modify the original state instead of the copied state.

Is there any simple way to overcome this?

Example:

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
  }
}

Now imagine a State that has a list of those 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;
     }
}

Update: May someone point me into a direction or point on some keywords I may search for ? This question seems to be very specific, but even after trying to solve this problem for many hours there seems to be no real solution.

EDIT: Excuse all the typos, duh

1

There are 1 best solutions below

1
On

One possible solution is to maintain versions of the class A or any subclasses inside it, rather than creating copies from outside. For example:

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;
    }
}

So in the end you are still dealing wih only 1 reference to A. It will also encapsulate the complexity of creating copies on every mutation inside the respective class.