Tuesday, December 31, 2013

In matters of style, swim with the current; in matters of principle, stand like a rock.

I like very much that quote in the title(by Thomas Jefferson).
I found it in the programming book "The pragmatic programmer" some months ago.

Inspired by that quote, for the end of 2013 I want to briefly write a little post about an interesting and distinctive object oriented principle: "Tell don't ask"

It encourages "NOT TO" retrieve the state from an object, "IF" it is going to be used by the client code to make a decission on what to do next.

In my opinion, the reason why this is important is because we want to avoid client's decision becoming dependant on some state that is not under their control. Also exposing unnecesarily the state of the object(unless immutable) to the client code may not always be desirable.
We should try as much as possible, to avoid giving to the client code clues about the state of the object they are calling.

Let's have a look at an example that does not worry much about this principle(The Ask don't tell way - The opposite of Tell don't ask):

 public class Bouncer {  
    //...  
    public Person letIntoParty(Person person) {  
     if(person.getAge() >= 18)  
       return person  
     throw new UnderAgeException(person);  
    }  
   //..  
 }  

At first glance, this code doesn't really look wrong, but the thing is, that the logic of the bouncers object, is dependant on the age of the person. This kind of invisible logical dependency that the bouncer has with the persons age, makes the software less object oriented(Is not capable of making decissions by its own).

It may sound funny but in a Tell don't ask scenario, the person should be aware that cannot get into the party if is under 18.

Now an example of how we could do the same via Tell don't ask:

 public interface BouncerFriendly {  
   //...  
   public Person goParty();  
 }   
 public class Person implements BouncerFriendly {  
   private int age;  
   //...  
   public Person goParty() {  
     if(age >= 18)   
      return this;  
     throw new UnderAgeException(this);  
   }  
   //...  
 }  

There can be different ways of implementing it, but I like to "program to an interface not an implementation". As you can see the decision is made by the person and we avoid giving to the client code clues about the state. Therefore dangerous client decisions based on the state of the object that they are calling are no longer possible.

best wishes for the year 2014!

Share with your friends