4

According to Effective Java's Item 15: Minimize Mutability, it is always better to make classes Immutable. According to that, how would I handle classes that are by nature given to change?

Some examples would be:

  • A Customer class, where an address or phone number can (and probably will) change.
  • A ShippingRule class, where shippers are selected based on different criteria. It makes sense that the rule should be editable...

In such cases, do we necessarily make them immutable? What other conventions are there?

Tulains Córdova
  • 39,201
  • 12
  • 97
  • 154
IntelliData
  • 981
  • 1
  • 8
  • 15
  • 7
    You're conflating immutability with business rules. Just because your object is itself immutable doesn't mean the values can't change. It means that when they do change, it will be reflected in the code by creating a new object with the new value. The previous instance of the object will be discarded. – Vincent Savard Apr 07 '17 at 17:49
  • In that case, I'm afraid I may not have sufficiently understood immutable objects; can you please elaborate? How would you change a property value of an Immutable object? – IntelliData Apr 07 '17 at 17:53
  • Suppose you need previous copies of class instances, a history. Immutable instances might be very useful in such a situation. On the other hand, if your code becomes more complex, and you are not making it more reliable at the same time, you have to question the immutability. – Frank Hileman Apr 07 '17 at 18:01
  • 2
    "How would you change a property value of an Immutable object?" – You can't. That's the definition of Immutable Object. You can, however, create a new object that has a different value for that property. – Jörg W Mittag Apr 07 '17 at 19:30
  • 2
    If you have any familiarity with strings at all, I find them very instructive when trying to understand how other immutable classes would be used. Everything you can do to "modify" a string returns a new string. Most programmers do this on a daily basis without thinking much of it. – Doval Apr 08 '17 at 17:34
  • By creating a new object to replace the old, you are moving the mutability (an improvement, but not totally immutable). To go 100% immutable, you will have to have an object with a start date, then create a new object with a new start date. Then the read operation will calculate the value based on the date given (for old dates it will return old values, for new dates it will return new values: in the past it was this and still is this for past dates. Nothing changed, as long as you nether run queries about what happened in the future). – ctrl-alt-delor Apr 08 '17 at 21:22
  • @richard: refer to [temporal database](https://en.m.wikipedia.org/wiki/Temporal_database) – Lie Ryan Apr 09 '17 at 01:50

1 Answers1

6

I read the chapter you stated, and I can see how you might be confused, as the chapter doesn't describe how you might use immutable objects.

Immutability is a core part of functional programming. To see how it works, consider this code:

MyImmutableClass newInstance = transform(MyImmutableClass originalInstance);

The transform method accepts the originalInstance object, transforms it (that transformation can be any operation), and returns a new object containing the transformation.

Why would you want to create a new object, instead of modifying an existing one?

  1. It creates a history of changes.
  2. It makes concurrency easier. Immutable objects are not subject to concurrency problems like race conditions. Functions using immutable objects can be easily decomposed into separate concurrent processes without problems.
  3. Immutable objects are easier to reason about.

In business applications involving CRUD operations, because you're typically already using a database with ACID guarantees, it's more common to simply mutate the values in the object you want to change, and then perform a Save (Update).

Robert Harvey
  • 198,589
  • 55
  • 464
  • 673
  • Immutability not only helps concurrency. In the single-threaded case, you are still sure that no methods you called between two points changed anything tacitly inside an immutable object, that an object passed as an argument to a method is guaranteed not to be changed inside it, no defensive copies needed, etc. – 9000 Apr 08 '17 at 05:46
  • @9000 So do you think all classes should be made immutable? And look at charlotte's answer, is that what should always be done? – IntelliData Apr 10 '17 at 13:41
  • @IntelliData: I see many benefits in immutable data. Still _some_ things are easier with mutable data (e.g. a picture as a large bitmap, or a database connection that can open and close). I try to treat all data as immutable unless I see a compelling reason not to. – 9000 Apr 10 '17 at 15:22