While you could have the immutable classes simply implement clone
to return references to themselves, I really don't see much value in using clone
on things that may or may not be mutable, absent some way of making mutable copes of immutable things and vice versa.
I would think it would be better for your base Matrix
class to include methods IsImmutable
and IsWritable
, along with AsImmutable
, AsMutable
, and AsNewMutable
methods; it should also include methods to read and write the matrix (though calling the "write" method on non-writable matrix should throw an exception).
Define static methods CreateImmutableMatrix
and CreateMutableMatrix
which, given a Matrix
, will create a new immutable or mutable matrix which is pre-initialized with the proper data.
Mutable classes should implement AsImmutable
to pass themselves to CreateImmutableMatrix
, AsMutable
to return themselves, and AsNewMutable
to pass themselves to CreateMutableMatrix
.
Immutable classes should implement AsImmutable
to return themselves, AsMutable
to call AsNewMutable
, and AsNewMutable
to pass themselves to CreateMutableMatrix
.
Read-only wrappers should implement AsImmutable
to call AsImmutable
on the wrapped objects, and AsMutable
and AsNewMutable
to call AsNewMutable
on the wrapped objects.
An object which receives a matrix which it may or may not need to copy or mutate may simply store it in a field (e.g. Foo
). If it needs to mutate the matrix, it can replace Foo
with Foo.AsMutable()
. If the object containing the matrix needs to be copied, the field should be replaced in the copy with either Foo.AsImmutable()
or Foo.AsNewMutable()
depending upon whether the field in the copy will likely need to be mutated.