Versions Compared

Key

  • This line was added.
  • This line was removed.
  • Formatting was changed.

...

Suppose you go to your well deserved holiday, and you give the key of your house to your brother, and ask him to keep an eye on it. When you return, he is waiting for you on the airport, and gives you back your key. It's harmless, you don't see a scratch on it. Yet, you'll ask him immediately whether everything is fine at home or not. The state of the key says nothing about the house of that key it is. Now suppose we have a data model, which uses a List internally to store the data, and generates events whenever new items are added to that List, or items are removed from it.

...

I'm sure now you have the point, but just allow me to emphasize it. The key is the reference returned by the getData method, and the house is the content of the list. In the model, whenever an item is added or removed, the notification is sent automatically. Then, for whatever reason (e.g. due to a misinterpreted performance enhancement), the List is exposed to the public. Yeah, the _data will refer to the very same List instance, regardless what happens in the code that calls the getData() method. But the content of the list is not safe any more. Whoever grabs a reference to the list (that's what the getData method provides), may make changes by adding or removing elements - and the model won't know anything about it. That's, ladies and gentlemen, is one of the best ways of inducing hardly discoverable, randomly occurring bugs into our application. In this particular case, the solution is simple - use the Collections class to create an immutable version of our list and provide that reference to the public. But if we have to allow the external code to change the content of the list, then instead of giving the reference, implement the Iterable interface, and return with a local implementation of the Iterator, which sends the proper notifications. But all these are possible only because we're talking about a collection. But the problem is more general than that - if part of the state of the object is another object (and a reference to that other object is held), then we shouldn't allow access to that other object, unless it is immutable. And how to do it in general? Sorry, no general solution exists. It's our responsibility to keep this rule.

...