Hi!
Attached you will find a zip with code for two simplified java
packages (example.immutable + example) containing mutable and
immutable versions of some example objects. Please read the comments
in the java-files for more details.
The intention of this experiment is to test and discuss some possible
solutions for a future version of the java-ref-impl. The approach is
based om discussions between me, Mikael and Mattias but possible
implementation errors are probably my fault ![]()
The class Tester.java has a main() method that shows usage and you can
see how a mutable herarchy is built up and then converted to an
immutable hierarchy. Please play around with the code and try to find
weak spots and problems in the approach.
There are many ways to do mutable/immutable pairs, some are described in
A. http://www.javalobby.org/articles/immutable/index.jsp
B. http://www.javaworld.com/javaworld/javaqa/2002-12/01-qa-1206-immutable.html
C. http://www.javaranch.com/newsletter/Apr2003/immutable.htm
The chosen apporach is most similar to what in [A] is called "Inverted
False Immutability", that has the following pitfalls described:
1. If a new method is added to the mutable (super) class, one have to 'remember' to
override that in the immutable sub class to throw an exception. I said remember; if you
don't get goose bumps from that word you haven't done much coding, or have way better
memory than me..
1a) If you look into the supplied code you will find that the
immutable versions of the classes contain almost no behaviour, almost
only delegation. The immutable clases could thus be auto-generated
from the mutable versions and should not be handwritten, thus
eliminating the risk of "forgetting". A potential reflection capable
framework for such generation is e.g.
http://apt-jelly.sourceforge.net/
1b) The RM should not change very often (as opposed to usual buisness
objects) and manual inspection of the conversion process and resulting
code should be possible.
2. The API for the immutable object is wrong, it contains the setXXX() methods. The
compiler won't help us since you can't make the overridden methods private. You will
only know if you are trying to break the immutability at runtime, if that code path is
executed. This anti-pattern is a good way to insert bugs..
2a) But as you see in the code example you can make them deprecated
with annotations (and/or javadoc tags). This will be noted by
developers already in many IDEs (e.g. overstrike in Eclipse) and will
certainly be caught by the compiler.
3. You have no control over what's actually happening in the mutable (super) class.
Maybe the implementor of that class thought it would be good to correct the date for
day time savings when the current time passes the cut-off time? Who knows, I have
seen stranger things written in code...
3a) In the ref-impl-project team we certainly do have control over
"what's actually happening in the mutable (super) class"
3b) There is not much state-changing behaviour in the RM/AM
3c) see 1b
There are many other things said in the code and code comments. The
question regarding if parents should be allowed to be mutable or not
might be worth discussiong. I can think of use cases where you want a
part of the hierarchy to be mutable and the rest immutable.
We have some other thoughts regarding future implementations too and
will get back to that later. But for now let's discuss this
experiment.
Best regards,
Erik Sundvall
http://www.imt.liu.se/~erisu/
P.s. Thomas please have a look at the approach in the zip too even
though it is in java
You might see some potential openEHR specific
pitfalls.
P.p.s. What's happening at UCL? Does anyone over there have any
thoughts about future changes in the java-ref-impl?
(attachments)
immutable-tests.zip (8.42 KB)