Versions Compared

Key

  • This line was added.
  • This line was removed.
  • Formatting was changed.
Comment: Migration of unmigrated content due to installation of a new plugin

There are many articles out there dealing of with the accessor and mutator methods (getters and setters). They came together with the Object-Oriented principles. Information hiding says that the internal state of an object must be hidden from the outer world. That is, the fields it uses shouldn't be available. Yet, sometimes we have to query the state of the object, and even may want to change that state. Directly accessing the field representing the state is considered to be a bad practice (the field shouldn't be available), therefore a method must be provided to retrieve the value of the field. This method is the accessor method (the getter). Similarly, a method might be provided to change the value of the corresponding field. This method is the mutator method (the setter). Usually, the signature of these methods follow the <Type> get<FieldName>() and void set<FieldName>(<Type> newValue) notation. So we are safe, we strictly follow the OO principles, right?

...

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.

Finally, since it is very rare that generally universally acceptable truth would exist, therefore it is worth to note that there are cases when both of the two rules above should be broken. One such case is the data object, traveling between the client and the server (or vice versa). There, it is not just well but even wished that the object be serialized upon sending, and deserialized upon receiving. There are general frameworks that use getters and setters during the serialization and deserialization. In this case it is allowed to "expose" implementation details - after all, we're not dealing with business processes right now, we have to take care of mere technical problems, namely transferring data from one computer (e.g. the server) to another (e.g. the client). So it's actually not breaking of any of the rules above. However, in these cases, extra care should be taken to avoid the misuse of these getters and setters - they are only for sending and receiving information, and not for any other purposes.