I give the orders around here!

I have been programming since I got my first Commodore 64 as a nine year old kid. However I still think I have so much to learn when it comes to writing good code.

In my quest to improve I have learnt many different languages. Most of them are predominantly object oriented (OO).

What suprises me though in most of the books, magazines and on-line articles that I have read is the amount of horrible OO code used in examples.

The most violated principle I see is the “Tell, Don’t Ask” principle. This principle states that an object should tell other objects what to do and not query other objects for state to make decisions (querying objects for state to make decisions is also referred to as ‘Feature Envy’). In Object Oriented Programming an object is defined as having state and operations that manipulate that state.

In his book ‘Holub on Patterns: Learning Design Patterns By Looking At Code’, Allen Holub includes a section in chapter one titled ‘Why getter and setter methods are evil’. He also contributed it as an article to JavaWorld. It should be a “must read” for any OO developer.

I have worked with developers whose first step after declaring attributes on a class is to add getters and setters. The JavaBean specification has a lot to answer for in promoting this culture. It was deemed a good way to write re-usable modular components but the world has come a long way since then.

Writing classes with getters and setters leads to procedural code. Logic that operates on data retrieved from getters ends up spread out across an application and is often duplicated across an application (violating another principle DRY – Don’t Repeat Yourself). This leads to unmaintainable code as any change to a class causes a ripple effect throughout the application.

By exposing the data you also prevent easy refactoring of the class because any change to the way an attribute is represented affects any other object that has access to that attribute.

Another side-effect of violating the Tell, Don’t Ask principle is that your tests end up being very state-based with stubs requiring a lot of expectations. This can make it very hard to understand what is actually being tested.

A third principle you will probably end up violating is the Principle of Least Knowledge (or LoD – Law Of Demeter). This law can be summarised as follows:

A class should only talk to its immediate friends and don’t talk to strangers.

By adding getters to your class you end up writing code like:

if (person.getAddress().getCountry() == "Australia") {

This violates the Law of Demeter because the caller is too intimate with Person. It knows that they contain an Address and that Address contains a country. It could be written like this instead

if (person.livesIn("Australia")) {

This does not violate the Law of Demeter as the caller is only talking to their immediate friend Person and they have no knowledge of the internals. From a Tell Don’t Ask perspective this is better because the logic for determining if the person lives in Australia is hidden within Person and if we decided to change how the country value is represented in Person it would not affect any other classes that depend on that value.

The other side effect of writing the code this way is that it displays the intent much clearer. That will be another topic that I will be touching on soon.

Some things to keep in mind to avoid violating the Tell Don’t Ask principle.

Think before hitting the hot keys in your IDE exercise the ‘5 Whys’ and ask yourself why you need to add a getter or setter in the first place.

Do not ask objects about their state, make a decision, then tell them what to do.

Operations belong with the class that owns the data.

Further Reading

A friend of mine is a strong advocate of this and has come up with the

East Oriented approach that explains this principle brilliantly.

Tell Don’t Ask and the effect on testing From Steve Freeman and Nat Pryce, authors of Growing Object-Oriented Software, Guided by Tests.

Share this: Twitter

Facebook

Like this: Like Loading...