Versions Compared

Key

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

...

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 Alternatively, and 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.

...

Conclusion 2: Whenever the accessor returns with objects, or the setter receives one, do not use allow the direct usage of that reference directly, unless the referred object is immutable.

...