Design Patterns – Clone/Copy Constructor and Child Class

design

I just want feedback on what one considers 'most elegant design' for a situation like this.

I have an object that is immutable with some (sort of) copy constructors to allow creating a similar but modified version of my immutable object. So something like this:

class ImmutableObject{
   Fee fee;
   Fi  fi;
   Fo fo;

   public ImmutableObject(Fee fee, Fi fi, Fo fo){
        this.Fee=fee;
        this.fi=fi;
        this.fo=fo;
   }

   public ImmutableObject(ImmutableObject cloneObj, Fee fee){
      this.fi=cloneObj.fi;
      this.fo=cloneObj.fo;
      this.fee=fee;
   }

   public ImmutableObject(ImmutableObject cloneObj, Fi fi){
      this.fee=cloneObj.fee;
      this.fo=cloneObj.fo;
      this.fi=fi
   }


   public ImmutableObject(ImmutableObject cloneObj, Fo fo){
      this.fi=cloneObj.fi;
      this.fee=cloneObj.fee;
      this.fo=fo;
   }
}

I'm now expanding this by creating a sub-class with extra behavior:

 Class ImmutableChild extends ImmutableObject{

   Fum fum;

   ImmutableChild(Fee fee, Fi fi, Fo fo, Fum fum){
      super(fee, fi, fo);
      this.fum=fum;
   }

The problem is that I have a collection of 'ImmutableObjects' that contain both original and child classes. When I try to clone them to get a new object with one modifid element My copy constructors will always create a class of parent type 'ImmutableObject' type and completely loose the state of 'fum' if I'm actually cloning the child class.

I can easily refactor this to meet any solution I want, copy constructor, clone methods etc. However, while I can get the behavior I want, I'm not sure what would be considered both elequant and non-ridged solution. What is the cleanest method to allow a method that will create a 'clone' of my object with one value modified which works well with children classes that expand functionality?

Best Answer

Were it not for the complication of accepting possible modifying arguments you would simply provide a virtual clone() method in ImmutableObject that instantiates and then returns a pointer to an ImmutableObject. Derived classes override the function and instantiate their own derived type but still return it as ImmutableObject.

As for the extra arguments passed to the "copy constructors", the code doing the copying or calling the clone() method is aware of these differences so can simply clone the object and then change the clone if and how required.

You might want to consider carrying simple type information in the base class - an enumeration would do - if you need to downcast a cloned object later.

Related Topic