Fowler: Explaining the principle of Tell Don't Ask (and why I don't use it in my own programming)

1,424 views
Skip to first unread message

philip schwarz

unread,
Sep 8, 2013, 6:55:21 AM9/8/13
to growing-object-o...@googlegroups.com

Martin Fowler tweeted this 3 days ago:

bliki: Explaining the principle of Tell Don't Ask (and why I don't use it in my own programming) http://martinfowler.com/bliki/TellDontAsk.html

Philip

Mike Stockdale

unread,
Sep 8, 2013, 10:50:40 AM9/8/13
to growing-object-o...@googlegroups.com
The key points:

He seems to agree with the underlying principle:

"I do look to co-locate data and behavior, which often leads to similar results."

Like any technique, it can be misused by unthinking application.

"I've seen it encourage people to become GetterEradicators, seeking to get rid of all query methods."

He feels it's a possible heuristic leading to good design, but not valuable enough to emphasize.

"For me, tell-don't-ask is a stepping stone towards co-locating behavior and data, but I don't find it a point worth highlighting."

I'd agree with almost all of the article, except I'd end with: For me, tell-don't-ask is a stepping stone towards co-locating behavior and data, and a useful design technique when applied thoughtfully.
--
Cheers,
Mike Stockdale

fitSharp
Syterra Software Inc.

Steve Freeman

unread,
Sep 8, 2013, 5:36:10 PM9/8/13
to growing-object-o...@googlegroups.com
These days, my "data" objects tend to immutability, so his example isn't so useful--and it doesn't help that the call is defined in terms of setting something rather than calling for a service.

I find that, for requests that change state, Tell Don't Ask is a pretty good heuristic, and that everyone should try writing getter-less code at least once in their lives.

S

On 8 Sep 2013, at 15:50, Mike Stockdale wrote:
> The key points:
>
> He seems to agree with the underlying principle:
>
> "I do look to co-locate data and behavior, which often leads to similar results."
>
> Like any technique, it can be misused by unthinking application.
>
> "I've seen it encourage people to become GetterEradicators <http://martinfowler.com/bliki/GetterEradicator.html>, seeking to get rid of all query methods."

Luca Minudel

unread,
Sep 9, 2013, 5:51:00 AM9/9/13
to growing-object-o...@googlegroups.com

Putting data and behavior is a guideline I tend to follow from the beginning when coding.
Sometimes I reach the point where the class become too big, I start to realize that the class at some point have more then one responsibility.
When I actively look to extract the extra responsibility, sometime I feel-see in the design the tension between SRP and Tell Don't Ask.
Sometime a different distribution of responsibilities remove this tension.
Other times I discover that it is something inherent with the problem, and then something like a visitor/smart-handler is required. That is a better way then using a getter, still it does not go in the direction of  Tell Don't Ask.


Anyone had similar experiences?
Anyone can figure out a simple example that reproduce this dynamic ?


Luca

Brice Dutheil

unread,
Sep 9, 2013, 7:08:56 AM9/9/13
to growing-object-o...@googlegroups.com
From some time I'm thinking about visitors as for when a class become too big it usually means the class has too much responsibility or too much behavior, then I'd like to refer to CCP / CRP to help refactoring. For example if there's too much behavior change, addition, removal, etc. then maybe a visitor could be useful and if appropriate package these visitor elsewhere.

Also I think TDA is the perfect tool to avoid breaking the Demeter Law. And also I find it a nice step for people that are interested to CQRS/ES or FP.


By the way there was a small discussion on twitter following this article announcement : https://twitter.com/martinfowler/status/375646667329908736








-- Brice


--
 
---
You received this message because you are subscribed to the Google Groups "Growing Object-Oriented Software" group.
To unsubscribe from this group and stop receiving emails from it, send an email to growing-object-oriente...@googlegroups.com.
For more options, visit https://groups.google.com/groups/opt_out.

WIL PANNELL

unread,
Sep 9, 2013, 7:56:19 AM9/9/13
to growing-object-o...@googlegroups.com
Can you spell the acronyms in your reply?

-- Brice


To unsubscribe from this group and stop receiving emails from it, send an email to growing-object-oriented-software+unsubscribe@googlegroups.com.

Nat Pryce

unread,
Sep 9, 2013, 8:51:18 AM9/9/13
to growing-object-o...@googlegroups.com
I agree with that rule of thumb 

- Tell Don't Ask for stateful code, typically code that reacts to events and coordinates activity. I'd like to write this as communicating sequential processes if only the language supported them well.

- Pure functional code elsewhere, which transforms immutable data structures.

I *think* that's what Martin is getting at.  What he writes as a mutable Embedded Document I'd prefer to write as composable, functional transforms.  But the concept is the same -- some parts of the system involve transforming data, some involve reacting and coordinating event flow.  Mixing the two concerns in the same part of the code leads to procedural spaghetti.


--

---
You received this message because you are subscribed to the Google Groups "Growing Object-Oriented Software" group.
To unsubscribe from this group and stop receiving emails from it, send an email to growing-object-oriente...@googlegroups.com.

For more options, visit https://groups.google.com/groups/opt_out.

Brice Dutheil

unread,
Sep 9, 2013, 1:12:09 PM9/9/13
to growing-object-o...@googlegroups.com
@Wil Sorry, here's the acronyms

TDA - Tell Don't Ask
CCP - Common Closure Princinple one of the additional object oriented principles
CRP - Common Reuse Principle ____same
CQRS - Command Query Segregation Principle
ES - Event Sourcing
FP - Functionnal Programming


-- Brice

Luca Minudel

unread,
Sep 10, 2013, 8:39:29 AM9/10/13
to growing-object-o...@googlegroups.com


> I'm thinking about visitors as for when a class become

I realize I should tell little more about visitors and smart-handlers because the former are used in a different way then one defined by the original design patter and the later is defined in a paper I haven't referenced. 

Smart handlers are defined in this paper: Mackinnon, T., Freeman, S., Craig, P. Endo-testing: unit testing with mock objects, in paragraph '4.3 Effects on coding style'.
Visitor's use is intended as described here: http://oredev.org/2012/sessions/less--the-path-to-better-design




> I'd like to refer to CCP / CRP to help refactoring.

Can you expand more about how  you use the CCP (Common Closure Princinple one of the additional object oriented principles) and CRP (Common Reuse Principle) to drive your refactoring?
I'm used to look at them at the packaging level of granularity, so I need some help to understand the use you do of them.


Luca 

-- Brice


To unsubscribe from this group and stop receiving emails from it, send an email to growing-object-oriented-software+unsubscribe@googlegroups.com.

Carlos Ble

unread,
Sep 11, 2013, 7:38:24 AM9/11/13
to growing-object-o...@googlegroups.com
Hi,
I find the principle very useful to combat against the "feature envy" smell which happens often when using anemic models. This is an "extract method" refactoring example promoted by the principle:

  1. // Code before refactoring 
  2. // Service class:
  3. ...
  4. public virtual void RequestPin(User user) {
  5. var newPin = PinBuilder.CreateNewPin();
  6. PinRepository.SaveNewPinFor(newPin, user.UniqueIdentifier);
  7. SmsProxy.SendSms(user.Phone, CreateSMSMessage(newPin));
  8. }
  9. ...

  10. ---------------------------------- 
  1. // Code after extracting methods: 
  2. // Service class:
  3. ...
  4. public virtual void RequestPin(User user) {
  5. var newPin = PinBuilder.CreateNewPin();
  6. user.ResetPIN(newPin, PinRepository);
  7. user.RequestSMS(CreateSMSMessage(newPin), SmsProxy);
  8. }
  9. ...
  10.  
  11. // User class:
  12. ...
  13. public void ResetPIN(string newPin, PinRepository pinRepository) {
  14. pinRepository.SaveNewPinFor(UniqueIdentifier, newPin);
  15. }
  16.  
  17. public void ReceiveSMS(string message, SmsProxy smsProxy) {
  18. smsProxy.SendSms(Phone, message);
  19. }
  20. ...

I've written a bit more on my blog:

Matt Wynne

unread,
Sep 11, 2013, 6:09:14 PM9/11/13
to growing-object-o...@googlegroups.com
I found your definition in the book - "tell objects, ask values" - really useful. I think that insight is missing from Fowler's article.

Brice Dutheil

unread,
Sep 13, 2013, 10:47:30 AM9/13/13
to growing-object-o...@googlegroups.com
Hi Luca

About CCP and CRP ; it always depends on the context, but usually when I refactor a class to extract behavior, I always ask myself these questions :
  • What is regularly changing in this class, attributes or behaviors ?
  • Is it possible to extract some behaviors, under an appropriate form (a visitor for example) ?
  • And for the interesting part when extracting these, I always ponder on the following cases :
    • If these classes should stay in the same package because their are ALWAYS used together, maybe I should package them together
    • But if these classes begin to show different change granularity (for exemple if behavior get modified or changed more regularly), instead it might be relevant to use a different package, this has the benefit of showing what is stable and is not.
That is how I mostly use CCP to help package refactored code. CRP however is kind of unpredictable and difficult to achieve successfully in the long term, so I use it rather to hold me up when I'd like to package things in different units.

In the end I'm speaking of the principles that Uncle Bob named, but it feels close in essence to refactor with GRASP patterns in mind (especially high cohesion and low coupling). They serve as a foundation when factoring out code.






-- Brice

Anthony Green

unread,
Sep 23, 2013, 3:27:09 AM9/23/13
to growing-object-o...@googlegroups.com
Matt Wynne wrote:
> I found your definition in the book - "tell objects, ask values" -
> really useful. I think that insight is missing from Fowler's article.

Is it possible the article is an extension of his concept of the Anemic
Domain Model
(http://www.martinfowler.com/bliki/AnemicDomainModel.html) ?

"the basic idea of object-oriented design; which is to combine data and
process together"

His preoccupation with this notion of OO dominating the rest of his
thinking on design?

Having read some of the discussion entries on the C2 wiki I no longer
expect we'll achieve consensus on OO strategies, only lively discussion.






Reply all
Reply to author
Forward
0 new messages