Getters and setters

From CSSEMediaWiki
Revision as of 23:13, 6 October 2008 by Dominic Winkler (Talk | contribs)
Jump to: navigation, search

<Long tedious background explanation of getters & setters goes here>

  • A 'Getter' also known as accessors are methods that return a vaue to the caller.
  • A 'Setter' also known as mutators are methods that that set a value for the caller.

The two should not be combined as this creates unexpected side effects for the unsuspecting developer. This idea is called Command query separation.

Using setters rather than having direct access to fields is good practice. It allows the class to maintain the integrity of the data enforce constraints, if there are any, on exactly what values can be set.

The problem with getters

Using getters can be useful for Reusability through self-encapsulation. It can however be misused very easily. The purpose of a getter is to retrieve information. If getters are mostly being used from outside the class to get access to member variables one should ask why is data and functionality not in the same place.

There is also the possibility that you are Getting out values to do work that the class should be doing for itself. This sometimes leads to breaking the <reverb> Law of Demeter </reverb>. In cases like this it is better to Tell, don't ask.

The above is just two ways of saying the same thing.

The alternative to setters

There is an also alternative to setters. That is immutable objects. Many programmers will already be using this concept in there programming as Java, C# and other languages force immutable strings on the programmer. The value of an immutable object is set at creation and can not be changed. This means no side effects. Many concepts will not work without the concept of immutable objects such as flyweight and the "canonical representation" mechanism for strings in Java.

Rule for good design, version 1:

  • Whenever you declare a field, foo, make it private.
  • Add a public getter called getFoo(), or isFoo() for booleans.
  • Make the return type of the getter the same as the field.
  • Add a public setter called setFoo() & pass a parameter of foo's type.
  • Inside the object, access the field directly.
  • Elsewhere, use the getters & setters.

Simple.

Except we just killed Encapsulation.

Rule for good design, version 2:

  • As above, but only add the getters &/or setters as necessary.

If the type or name of foo changes, should we change the methods too?

If we do, are we Information hiding?

Some gurus go further, suggesting that we should always call getters & setters, even from inside the object containing the field. The only methods allowed to touch the field directly are its getter & setter.

Rule for good design, version 3:

  • As above, but always use the getters & setters.

This idea is explained by Ken Auer 1995. But first, it helps to realise there is more than one Encapsulation boundary behind which we might hide fields.

See Also

  • Riel's heuristics 9.2 Do not change the state of an object without going through its public interface.
Personal tools