The Problem with Immutability
I’m writing this partly because I think there must be a happy solution and I just can’t find it.
I love immutability. Not all the time, but many times. I’d like to identify values which either because problems when they are changed, or they just do nothing. Of course reference variables generally need to be immutability, but they can also generally be initialized without any data – for example you can set a collection variable to an empty list in the declaration or the constructor.
The problem occurs with data happy classes – classes with strings or dates or integers or strings – where it is either dangerous or useless to set the values.
In traditional coding where you explicitly call a constructor, all is happy because you can create read only variables. You can assign to these variables in the constructor and they can’t be assigned to again.
But enter composition, MEF, IoC, whatever. Now, how do you manage those immutable values?
I’ve come up with four solutions:
a) Provide an Initialize method with positional parameters
b) Provide an Initialize method with optional named parameters
c) Write ugly code that tracks values and issues runtime errors
d) Provide a second interface that allows the sets
e) Use a singleton factory strongly bound to the actual class
f) Forget immutability
I’ll veto c for my work. Not only is it extra stupid code everywhere, but it throws runtime, not compile time errors.
If you need things to be “kind of, sort of” immutable, the interface trick would work. In some cases you might be able to limit visibility of the interface. But it’s not immutable.
I hate initialize methods. You have to remember to call them and its extra thinking. Without optional/named parameters they are extremely fragile to parameter list changes. And, it would be so weird to call Initialize twice on an object that I’m OK with the runtime error for that, and it can refuse to reset the values so you have nearly true immutability.
It’s not true immutability because the variables must be writable from within the class – for example, you could use private setters. This means within the class, the values can be changed rendering them less than fully immutable.
You could solve this problem if you created custom factories for every class you would instantiate items of. Instead of retrieving the new value via composition/MEF, retrieve the singleton factory. The factory could be hard wired to the actual class and thus directly call the constructor. A method like “Instantiate” could take as many parameters as needed, and could use optional and named parameters to avoid parameter list fragility issues.
This leaves me less than enamored with PartInitializer. It encourages us to skip immutability or to take shortcuts that leave our classes less than fully immutable. I’m not enamored with custom factories either. They are only a few lines of code, but they barf an implementation detail all over our code. Significant ceremony.
I’d beat up on the MEF team if I could figure out a way they could solve this with minimal ceremony.
Anyone have a great solution?