Immutable Value Objects in PHP

Yesterday I tweeted:

Modern object-oriented programming languages need support for immutable Value Objects. #DDD

The “DDD” in that tweet stands for Domain-Driven Design. There were several interesting responses to this tweet. Kevin Schroeder thought that it made a lot of sense but pointed out that “need” was a bit of a strong word. I should have instead said that this would be a “useful” feature. Matthew Weier O’Phinney shared an example of making an immutable object in PHP. Ralph Schindler suggested throwing an exception so as not to silently reject an attempt to modify the object’s state. Nicolas BĂ©rard-Nault had a similar suggestion of implementing PHP’s __set magic method and throwing an exception so that new public attributes cannot be assigned and also not making any methods that change the state of the object. Giorgio Sironi suggested that PHP’s “private” keyword was all you needed to support immutable Value Objects.

The above suggestions are all useful when implementing immutable Value Objects in PHP. I would also add that you need to make the class “final” to truly guarantee that it’s immutable. This is so that someone can’t extend the class and add (or override) methods that change state (although I suppose if you made the __set method final and had it throw an exception that should do the trick since you wouldn’t be able to change any properties).

Regardless, all of these attempts to guarantee immutability miss the point. I don’t need to make sure the class is immutable when its defined, I need to know in my client code that it’s immutable. In other words, I need a contract that says the object is immutable. None of the above workarounds give you an explicit contract that the object is immutable. Hopefully you’re working on a team where you trust that if a teammate tells you that something is an immutable Value Object, it is immutable. In fact, I wouldn’t normally bother doing any of the above tricks to absolutely guarantee that the object is immutable. This is because you still can’t tell by looking at the object that it is immutable without inspecting its implementation. A built-in language feature would be useful because it would provide an explicit contract that the object is immutable.

9 Comments

  1. Peter
    Posted September 30, 2010 at 2:53 pm | Permalink

    I agree. A language feature would be the most solid approach. All other approaches either take too much effort or can be circumvented. For instance, Matthew’s approach (I am sure it was just a quick proof of concept) does not take references into account.

    $v = new Immutable(array(‘foo’ => ‘bar’, ‘bar’ => ‘baz’));
    $t =& $v->baz;
    $t = 1;
    var_export($v);

  2. Posted October 1, 2010 at 12:21 am | Permalink

    Actually, with Matthew’s example you don’t even need references as the values are stored as public properties.

    This should work better:
    http://paste2.org/p/1012059

  3. Posted October 1, 2010 at 3:22 am | Permalink

    Excelent idea, I would also love to see operator overloading on those ValueObjects (but not on regular objects).

  4. Posted October 1, 2010 at 4:49 am | Permalink

    Hi, you mention several times that you require an “explicit contract that the object is immutable”, but you don’t give an example of a case where you would need it, or of how it might look and act in code. I wonder if those might help people see where you’re coming from?

  5. Posted October 1, 2010 at 5:00 am | Permalink

    I don’t get it: what design problems are there that need something immutable.

    How are you as the author of the code able to know your immutable object really needs to be unchangeable in every possible imaginable scenario?

    To put it more concisely, if it’s immutable; how are you meant to mock it out in unit tests? Or what do you gain by making it untestable?

  6. Posted October 1, 2010 at 8:03 am | Permalink

    Hi,

    Quick hack http://github.com/mkoppanen/php-immutable seems to work OK for this purpose.

  7. Posted October 1, 2010 at 12:46 pm | Permalink

    The most important point to take out of this discussion, which Evans cited in the original DDD book, is that even if a concept does not exist at the language level, it is still valuable and can be adopted by a coscientious team of programmers.
    “[…] the lack of direct language support for a conceptual distinction does not mean that the distinction is not useful. It just means that more discipline is needed to maintain the rules that will be only implicit in implementation. This can be reinforced with naming conventions, selective documentation, and lots of discussion.”
    Unfortunately, our favorite language (PHP) is bloated with features like Late Static Bindings instead of supporting DDD concepts. 🙂

  8. Posted October 1, 2010 at 8:05 pm | Permalink

    @Peter: Interesting scenario. I suppose the original object would be completely replaced in that situation so would not technically be immutable.

    @sokzzuka: Yes, operator overloading would be a neat feature too. Would fit well with the “closure of operations” concept.

    @Simon Harris: I’m not sure what this contract would look like in code, but the idea is similar to the contract you give when implementing an interface.

    @Daniel O’Connor: I’ll write another blog post about how immutable Value Objects are useful. One benefit is that it gives you the flexibility of passing the object around without worrying about its state getting changed by some other code.

    @Mikko Koppanen: I’m not familiar with PHP internals, so not sure how to read this. It looks like I would have to extend Immutable in order to have an immutable object. Interesting approach. Not quite what I was envisioning, but it does meet the requirements I outlined: the object is immutable and the fact that its an instance of Immutable provides a contract to client code that it’s immutable.

    @Giorgio: Agreed. That’s exactly what I was getting at when I talked about trusting your teammates. There’s nothing currently preventing PHP developers from creating immutable Value Objects. Language support would be a nice-to-have.

  9. Posted October 2, 2010 at 3:16 am | Permalink

    The value objects could also be passed by copy like primitive types. Also if we had such objects, we could replace primitive types with them in namespaced code – like ‘use MyString as string’ (instead of autoboxing), so $foo = ‘bar’ would be equivalent to $foo = new MyString(‘bar’)

One Trackback

  1. […] to his blog about a subject he’s recently been learning about, Domain-Driven Design, and how immutable value objects could be useful in PHP. Yesterday I tweeted: Modern object-oriented programming languages need support for immutable […]