How to choose between Tell don't Ask and Command Query Separation?
- by Dakotah North
The principle Tell Don't Ask says:
you should endeavor to tell objects what you want them to do; do not
ask them questions about their state, make a decision, and then tell
them what to do.
The problem is that, as the caller, you should not be making decisions
based on the state of the called object that result in you then
changing the state of the object. The logic you are implementing is
probably the called object’s responsibility, not yours. For you to
make decisions outside the object violates its encapsulation.
A simple example of "Tell, don't Ask" is
Widget w = ...;
if (w.getParent() != null) {
Panel parent = w.getParent();
parent.remove(w);
}
and the tell version is ...
Widget w = ...;
w.removeFromParent();
But what if I need to know the result from the removeFromParent method? My first reaction was just to change the removeFromParent to return a boolean denoting if the parent was removed or not.
But then I came across Command Query Separation Pattern which says NOT to do this.
It states that every method should either be a command that performs
an action, or a query that returns data to the caller, but not both.
In other words, asking a question should not change the answer.
More formally, methods should return a value only if they are
referentially transparent and hence possess no side effects.
Are these two really at odds with each other and how do I choose between the two? Do I go with the Pragmatic Programmer or Bertrand Meyer on this?