We all know about the advantages of immutable objects. Most of the immutable objects that we use are model objects that tend to have a lot or properties. The question is how to initialize those properties without creating a telescoping initializer.
Immutable Objects in Cocoa
First idea that comes to mind is to follow the steps of the platform. Cocoa objects are either mutable or immutable. A good example of such object might be a NSURLRequest which has quite a lot of properties. We use its mutable counterpart NSMutableURLRequest to change the values of those properties. NSMutableURLRequest is a subclass of NSURLRequest which in turn implements NSCopying and NSMutableCopying protocols. We could do the same with our own classes.
Let’s implement a User class and its mutable counterpart:
Now we are able to use those classes the same way we use NSURLRequest. However, there are several problems with this approach:
Requires defensive copying to prevent accidental sharing of instances of MutableUser class where immutable User is expected
We had to use four lines of code for a single name property
We limited our ability to extend class hierarchy
Fortunately there is an alternative way to create immutable objects which is an overlooked builder pattern. It is a very simple pattern which addresses all those problems.
Let’s dive straight into implementation but this time we will start with a base class for our model objects - Entity.
Entity class has no mutable counterpart which means that defensive copying is no longer required. We also used just two lines of code for an ID property.