f



don't tell don't ask

I'm still struggling with OO concepts. I've read several books and
studied various OO languages, but I don't really feel I have a good
grasp of the concepts.

I like the sound of the "tell, don't ask" model, where networks of
objects are asked to perform the work they are responsible for, rather
than asking objects to give you information (like a string) that you
do something with. But, I get confused when I try to apply the idea to
a program design.

The only way I can think of avoiding asking objecs for information is
if the program consists of nothing but one object of class "Program"
with one method called "execute" that does everything.

I've seen an example of bad design:

AssociativeArray c = object.getEmployees()
for each employee in employees:
	c.put(employee.name(), employee)

the "tell don't ask" version of which could be:

object.addEmployees(employees);

So, "object"'s class supports the "tell model", by allowing you to
tell it to add employees rather than asking it for a map to modify.

But, doesn't that mean that "employees"'s class has to support the
"ask model", so that it "object" can get each of the "employee" objects and
their names?

Is there a way to actually use "tell" insead of "ask", through
out. Or, how do you categorize when you should use "tell" and when you
should use "ask"?
0
none90 (22)
2/12/2007 2:09:35 AM
comp.object 3218 articles. 1 followers. Post Follow

14 Replies
1186 Views

Similar Articles

[PageSpeed] 34

Frank Fredstone <none@not.no> writes:
>AssociativeArray c = object.getEmployees()
>for each employee in employees:
>	c.put(employee.name(), employee)
>the "tell don't ask" version of which could be:
>object.addEmployees(employees);

  One possibility:

employees.add_all_pairs_of_name_and_employee_to_map( c );

  Or using the notation [x|f(x)] for a block object ith the
  parameter �x�:

employees.for_each_employee_do[ e | e.with_name_do[ n | c.put( n, e ); ]]

  The blocks are passed into the objects as arguments to the
  operations �for_each_employee_do� and �with_name_do�, 
  so the objects do not return values such as �e� or �n�.

0
ram (2986)
2/12/2007 2:32:05 AM
ram@zedat.fu-berlin.de (Stefan Ram) writes:

> Frank Fredstone <none@not.no> writes:
>>AssociativeArray c = object.getEmployees()
>>for each employee in employees:
>>	c.put(employee.name(), employee)
>>the "tell don't ask" version of which could be:
>>object.addEmployees(employees);
>
>   One possibility:
>
> employees.add_all_pairs_of_name_and_employee_to_map( c );
>
>   Or using the notation [x|f(x)] for a block object ith the
>   parameter �x�:
>
> employees.for_each_employee_do[ e | e.with_name_do[ n | c.put( n, e ); ]]
>
>   The blocks are passed into the objects as arguments to the
>   operations �for_each_employee_do� and �with_name_do�, 
>   so the objects do not return values such as �e� or �n�.

Well, your examples uses different objects (employees and
a map) instead of (object and employees).

But, if I change your first example to

employees.add_all_pairs_of_name_and_employee_to_object(object)

I suppose that uses the "tell model" for both classes.

It seems disconcerting to me that Employees would have to have a
method specifically for interfacing with "object" objects, though. If
there became a reason to have an ineraction between an Employeees
object and some other object, would I then have to modify Employees to
have a method specifically for that other class? For example:

employess.add_employee_to_some_other_object(some_other_object)
employees.add_employee_to_yet_another_object(yet_another_object)

0
none90 (22)
2/12/2007 3:55:08 AM
"Frank Fredstone" wrote:
> I'm still struggling with OO concepts. I've read several books and
> studied various OO languages, but I don't really feel I have a good
> grasp of the concepts.
>
> I like the sound of the "tell, don't ask" model, where networks of
> objects are asked to perform the work they are responsible for, rather
> than asking objects to give you information (like a string) that you
> do something with. But, I get confused when I try to apply the idea to
> a program design.

My take on the "tell, don't ask" approach is that objects announce 
(tell) when something happens. This could be, for example, when they're 
finished with a task or an event outside of the system occurs and its 
their job to let interested parties know about it.

> But, doesn't that mean that "employees"'s class has to support the
> "ask model", so that it "object" can get each of the "employee" 
> objects and
> their names?

In my opinion, it's ok to have "getters" that expose an object's 
properties. One wants to be careful not to overdo it; you'd like the 
interface for a class to be as narrow as possible, but sometimes it just 
makes sense to have a getter for a particular property. A "Name" 
property seems reasonable for an Employee class. The question I'd have 
would be whether or not to make this property mutable (probably not). 
But then it's hard to judge what kind of interface a class should have 
in a vacuum. You really need to know more about the overall problem 
being solved. But as a general rule, I don't have a problem with a class 
providing a few properties that can be queried through "getters."

In other words, I don't have a problem with an object being asked to 
give more information about itself. 


0
2/12/2007 4:05:35 AM
Frank Fredstone <none@not.no> writes:
>>employees.add_all_pairs_of_name_and_employee_to_map( c );
>Well, your examples uses different objects (employees and
>a map) instead of (object and employees).

  I call an �associative array� a �map�, but this is not
  intended to be another class or object - just another name for
  the same thing.

>But, if I change your first example to
>employees.add_all_pairs_of_name_and_employee_to_object(object)

  My first suggestion is intended to replace the statement:

for each employee in employees:
	c.put(employee.name(), employee)

  This statement contains �c�, not �object�.
  Therefore, my first suggestion also contains �c�, not �object�.

>It seems disconcerting to me that Employees would have to have a
>method specifically for interfacing with "object" objects, though. 

  My first suggestion was:

employees.add_all_pairs_of_name_and_employee_to_map( c );

  It does not require �employees� to have a method for
  objects with the specific class of �c�. Instead, 
  �employess� only needs requires c's �put� operation. 
  Therefore, it accepts any object with such a �put�
  operation of two arguments.

>If there became a reason to have an ineraction between an
>Employeees object and some other object, would I then have to
>modify Employees to have a method specifically for that other
>class? For example:
>employess.add_employee_to_some_other_object(some_other_object)
>employees.add_employee_to_yet_another_object(yet_another_object)

  The other object needs to support an operation

      void put( object, object )

  Because the operation is called �put�, not �add�, I now would
  like to change my naming suggestion from

employees.add_all_pairs_of_name_and_employee_to_map( c );

  to

employees.put_all_pairs_of_name_and_employee_to_map( c );

  , though.
 
0
ram (2986)
2/12/2007 9:35:53 AM
Responding to Fredstone...

I agree with Wavemaker; the OO view of "tell; don't ask" is necessarily 
different than the procedural view...

> I'm still struggling with OO concepts. I've read several books and
> studied various OO languages, but I don't really feel I have a good
> grasp of the concepts.
> 
> I like the sound of the "tell, don't ask" model, where networks of
> objects are asked to perform the work they are responsible for, rather
> than asking objects to give you information (like a string) that you
> do something with. But, I get confused when I try to apply the idea to
> a program design.

This view is just plain wrong in the OO world.  OO methods are 
/supposed/ to access the knowledge they need on an as-needed basis 
because the OOA/D model of behavior communication is asynchronous. That 
implies an arbitrary delay is possible between when a message is 
generated and when the response is executed. (That's because the OOA/D 
must be unambiguously implementable in inherently asynchronous and/or 
concurrent environments at OOP time as well as synchronous environments.)

However, data integrity becomes a mess with that model if it is passed 
in messages because of the potential delay. So in OOA/D knowledge access 
is always synchronous (getters/setters are aka synchronous services). 
That's the only way to ensure timely data and the OOP implementation 
must provide infrastructure to ensure accessing the data behaves as-if 
it were synchronous, even in distributed implementations. That makes it 
much easier to manage scope for data integrity during OOP. So the method 
always asks for the data it needs and in a well-formed OO application 
messages very rarely carry data packets. (There are data packets only 
when requirements demand "snapshots", such as processing data from 
multiple sensors that in from the same time slice.)

Message and method are separated in the OOA/D so that one can eliminate 
hierarchical implementation dependencies. The 'tell' part refers to the 
fact that all behavior messages are announcements (I'm done). They tell 
whoever is listening that something was done that changed the state the 
the solution. Then the sender of the message only needs to know what it 
did and has no expectation of what will happen as a consequence. IOW, 
what the message receiver does with that information is a personal 
matter for the receiver. The sender doesn't even need to know who will 
receive the message.  Routing the messages to the right receiver is done 
at a different level of abstraction (e.g., a UML Interaction Diagram).

Conversely the 'ask' part refers to an expectation that a specific 
receiver will do something in particular (Please Do This). That is a 
no-no in an OO context because for the message sender to have that 
expectation it needs to know: (A) that someone specific cares what it 
did; (B) they have a specific behavior responsibility; and (C) that 
responsibility is what needs to be done next in the overall solution. 
All of those break OO encapsulation but the last is especially insidious 
because it hard-wires the overall solution sequence into the sender 
implementation.

> The only way I can think of avoiding asking objecs for information is
> if the program consists of nothing but one object of class "Program"
> with one method called "execute" that does everything.
> 
> I've seen an example of bad design:
> 
> AssociativeArray c = object.getEmployees()
> for each employee in employees:
> 	c.put(employee.name(), employee)
> 
> the "tell don't ask" version of which could be:
> 
> object.addEmployees(employees);

I agree the example is poor practice, but I don't think it has anything 
to do with "tell, don't ask".  "object" is clearly a collection class 
that implements a 1:* relationship to Employee in the OOA/D. A such its 
natural responsibilities are to manage the collection. So it would 
logically have "add", "remove", "get", etc. responsibilities when one 
abstracted the concept of a collection from the problem space. So there 
is no point in having an intermediary collection (AssociativeArray) to 
implement those notions.

[BTW, the example seems curious from another standpoint. Why is there a 
second collection of Employees ("employees")? That would only be 
justified if there were another 1:* relationship to Employee that 
involved a different set of employees in the collection. But if that 
were true, I would expect there would be some selection criteria to 
apply for the subset.

My point here is not to critique the example, but to point out that the 
use of collections and their management will depend on the specifics of 
the problem. "tell, don't ask" is not relevant here because the problem 
space is dictating the relationship collections and the collaborations 
that navigate them. IOW, problem space abstraction determines what 
collections are needed and what responsibilities they must have. "Tell, 
don't ask" only becomes relevant when one constructs the behavior 
methods that navigate those relationships during collaborations.]


*************
There is nothing wrong with me that could
not be cured by a capful of Drano.

H. S. Lahman
hsl@pathfindermda.com
Pathfinder Solutions
http://www.pathfindermda.com
blog: http://pathfinderpeople.blogs.com/hslahman
"Model-Based Translation: The Next Step in Agile Development".  Email
info@pathfindermda.com for your copy.
Pathfinder is hiring: 
http://www.pathfindermda.com/about_us/careers_pos3.php.
(888)OOA-PATH



0
h.lahman (3600)
2/12/2007 7:39:25 PM
ram@zedat.fu-berlin.de (Stefan Ram) writes:

> Frank Fredstone <none@not.no> writes:
>>>employees.add_all_pairs_of_name_and_employee_to_map( c );
>>Well, your examples uses different objects (employees and
>>a map) instead of (object and employees).
>
>   I call an �associative array� a �map�, but this is not
>   intended to be another class or object - just another name for
>   the same thing.

I didn't state what my example was doing clearly I think.

The example was showing the interaction betwen an object named
"object" of some class (let's say it's Organization) and another
object called "employees" of some class (let's say it's Employees).

Assuming the premise of my post "tell" is good, "ask" is bad, the "bad
way" was for Organization to allow you to ask it for a map to modify:

AssociativeArray c = object.getEmployees()
for each employee in employees:
	c.put(employee.name(), employee)

This is supposed to be a typical example of "asking" an object for
something that you modify, rather than "telling" the object to perform
some operation.

The "good way" was for Organization to allow you to tell it to add
emloyees to itself:

object.addEmployees(employees);

My question was then, doesn't that imply that Employees needs to
support the "ask" model though?

I can get from your example that it could be possible for Organization
to allow an "add" operation and then use your

employees.add_to(object)

which is then "tell model", but, an Organization might need to have
things other than employees added to it, so an "add" method might not
be suitable, and the representation of an employee in an Organization
could change to require something other than a map of employees by
name.

I suppose there could be an addEmployee method on Organziation and
Employees.add_to could know that, but then doesn't that mean that
Employee has to support the "ask model"?

>>But, if I change your first example to
>>employees.add_all_pairs_of_name_and_employee_to_object(object)
>
>   My first suggestion is intended to replace the statement:
>
> for each employee in employees:
> 	c.put(employee.name(), employee)
>
>   This statement contains �c�, not �object�.
>   Therefore, my first suggestion also contains �c�, not �object�.

Right, but "c" only exists in the supposedly "bad way" of doing
things. The problem I was posing was one between "object" and
"employees".

Maybe you are saying that it is a good idea to ask employees for a map
to modify.

"Wavemaker" <jabberdabber@BiteMeHotmail.com> writes:

> My take on the "tell, don't ask" approach is that objects announce 
> (tell) when something happens. This could be, for example, when they're 
> finished with a task or an event outside of the system occurs and its 
> their job to let interested parties know about it.

I think this doesn't match what I've been reading referred to as "tell,
don't ask". I keep coming across it while I'm looking into testing and
mock objects, maybe it's a fringe idea.

I've seen "tell, don't ask" expressed in Allen Holub's book 'Holub on
Patterns' in the section "Getters and setters are evil", and on this
web page:

http://www.pragmaticprogrammer.com/ppllc/papers/1998_05.html

By "tell" they seem to mean telling objects to perform some action
rather than asking objects for information that you will then do
something with.

Allen Holub's argument for why it tends to be bad to ask for objects
for information about their state, is that it spreads dependencies on
the internal state of an object around to other objects.

He also argues that the place where getters/setters are not evil is
where you bump up against the "procedural boundary" of the system or
operating system that you are interfacing with. Or, if you need your
objects to be unusually flexible in how they can interact with other
objects, like if you are writing a general class library.

However, this is all to vague for me, and that's really what I'm
asking for is some less vague guidelines that someone can express an
opinion about.

"H. S. Lahman" <h.lahman@verizon.net> writes:

> Responding to Fredstone...
>
>> I like the sound of the "tell, don't ask" model, where networks of
>> objects are asked to perform the work they are responsible for, rather
>> than asking objects to give you information (like a string) that you
>> do something with. But, I get confused when I try to apply the idea to
>> a program design.
>
> This view is just plain wrong in the OO world.  OO methods are
> /supposed/ to access the knowledge they need on an as-needed basis
> because the OOA/D model of behavior communication is
> asynchronous.

I don't understand what you are describing as synchronous or
asynchronous about either "tell" or "ask" model methods, I think they
are both synchronous.

But, I think you might not be refering to the same thing as I am about
"tell, don't ask". By "tell" I mean methods that tell an object to
perform some processing, like "add an employee to your organization",
and by "ask" I mean methods that ask for data that you can then do
processing with yourself, like "give me a map that I can add employees
to".

0
none90 (22)
2/13/2007 5:30:59 AM
This article really helped me out in this area

http://www.pragmaticprogrammer.com/ppllc/papers/1998_05.html



Frank Fredstone wrote:
> I'm still struggling with OO concepts. I've read several books and
> studied various OO languages, but I don't really feel I have a good
> grasp of the concepts.
> 
> I like the sound of the "tell, don't ask" model, where networks of
> objects are asked to perform the work they are responsible for, rather
> than asking objects to give you information (like a string) that you
> do something with. But, I get confused when I try to apply the idea to
> a program design.
> 
> The only way I can think of avoiding asking objecs for information is
> if the program consists of nothing but one object of class "Program"
> with one method called "execute" that does everything.
> 
> I've seen an example of bad design:
> 
> AssociativeArray c = object.getEmployees()
> for each employee in employees:
> 	c.put(employee.name(), employee)
> 
> the "tell don't ask" version of which could be:
> 
> object.addEmployees(employees);
> 
> So, "object"'s class supports the "tell model", by allowing you to
> tell it to add employees rather than asking it for a map to modify.
> 
> But, doesn't that mean that "employees"'s class has to support the
> "ask model", so that it "object" can get each of the "employee" objects and
> their names?
> 
> Is there a way to actually use "tell" insead of "ask", through
> out. Or, how do you categorize when you should use "tell" and when you
> should use "ask"?
0
mat6682 (2)
2/13/2007 2:49:21 PM
Mat Taylor <mat@doc-net.com> writes:

> This article really helped me out in this area
>
> http://www.pragmaticprogrammer.com/ppllc/papers/1998_05.html

Yes, that article is really what my question is about. In fact I site
it in this thread.

In the example in that article, this is bad:

SortedList thingy = someObject.getEmployeeList();
thingy.addElementWithKey(foo.getKey(), foo);

and this is good:

someObject.addToThingy(foo);

Let me change the example a little. This is bad:

SortedList thingy = someObject.getEmployeeList();
thingy.addElementWithKey(foo.getKey() + "_" + foo.getId()
                         + "_" + foo.getBuilding(), foo);

and this is good:

thingy.addToThingy(foo);

My question then is, doesn't this mean that foo has to use "ask"
instead of "tell"? Doesn't addToThingy have to know that it can call
foo.getKey(), foo.getId() and foo.getBuilding()? How do you decide
when it's okay to use "ask" and when it's okay to use "tell"?

0
none90 (22)
2/13/2007 5:40:44 PM
"Frank Fredstone" wrote:
>
> In the example in that article, this is bad:
>
> SortedList thingy = someObject.getEmployeeList();
> thingy.addElementWithKey(foo.getKey(), foo);

The reason why the above is bad is that it breaks encapsulation. 
Apparently, someObject is responsible for managing a list of empolyees. 
By exposing its collection of employess publicly, any can get at it and 
do anything they want. Thus someObject no longer has control over its 
collection.

> Let me change the example a little. This is bad:
>
> SortedList thingy = someObject.getEmployeeList();
> thingy.addElementWithKey(foo.getKey() + "_" + foo.getId()
>                         + "_" + foo.getBuilding(), foo);
>
> and this is good:
>
> thingy.addToThingy(foo);

This requires the SortedList class know how to add a foo object. 
Generic, all-purpose container classes usually don't have that type of 
knowledge. I suppose foo could implement an interface that would allow 
it to be added to the SortedList as you have above without having to 
give SortedList specialized knowledge of foo (it only has to know the 
interface).

> My question then is, doesn't this mean that foo has to use "ask"
> instead of "tell"? Doesn't addToThingy have to know that it can call
> foo.getKey(), foo.getId() and foo.getBuilding()?

Yup, see my point above.

> How do you decide when it's okay to use "ask" and when it's okay to 
> use "tell"?

In this case, it looks like foo represents a "dumb data object." These 
are objects that don't have a lot of responsibility; they just represent 
information. It's ok for these types of objects to provide "getters" 
that allow you to query them for information. Usually, one wants to 
limit the mutability of such objects as much as possible, however, 
especially if they're being passed around.

At any rate, decide what responsibilties a class has within a problem 
space. Look at how it will interact with other classes. It may be that 
they need to expose certain properties so that other classes can "ask" 
them for needed information. What you may wind up with are a few active 
classes that pass dumb objects between them, like messages.

I guess what I'm trying to say is that I don't usually think about this 
question as I'm writing/designing my classes. It kind of takes care of 
itself. 


0
2/13/2007 11:41:14 PM
"Frank Fredstone" <none@not.no> wrote in message
news:87y7n2c5wj.fsf@not.no...
....
> Yes, that article is really what my question is about. In fact I site
> it in this thread.
>
> In the example in that article, this is bad:
>
> SortedList thingy = someObject.getEmployeeList();
> thingy.addElementWithKey(foo.getKey(), foo);
>
> and this is good:
>
> someObject.addToThingy(foo);
>
....

Put aside OO and its rules, first sample is nightmare in mulithreaded/async
envorioment (when locking is needed).

Regards,
Goran


0
gsliskov (30)
2/15/2007 1:18:27 PM
On Feb 11, 9:09 pm, Frank Fredstone <n...@not.no> wrote:
> I'm still struggling with OO concepts. I've read several books and
> studied various OO languages, but I don't really feel I have a good
> grasp of the concepts.
>
> I like the sound of the "tell, don't ask" model, where networks of
> objects are asked to perform the work they are responsible for, rather
> than asking objects to give you information (like a string) that you
> do something with. But, I get confused when I try to apply the idea to
> a program design.
>
> The only way I can think of avoiding asking objecs for information is
> if the program consists of nothing but one object of class "Program"
> with one method called "execute" that does everything.
>
> I've seen an example of bad design:
>
> AssociativeArray c = object.getEmployees()
> for each employee in employees:
>         c.put(employee.name(), employee)
>
> the "tell don't ask" version of which could be:
>
> object.addEmployees(employees);
>
> So, "object"'s class supports the "tell model", by allowing you to
> tell it to add employees rather than asking it for a map to modify.
>
> But, doesn't that mean that "employees"'s class has to support the
> "ask model", so that it "object" can get each of the "employee" objects and
> their names?
>
> Is there a way to actually use "tell" insead of "ask", through
> out. Or, how do you categorize when you should use "tell" and when you
> should use "ask"?

I get the impression that there is some confusion here between "tell,
don't ask" and the Law of Demeter. Your code example breaks the
latter, not the former. An example that breaks the former would be
something like:

if ( someObject.isInStateFoo() )
   someObject.setStateBar();

IOW, breaking tell don't ask means you shouldn't have to ask them
about their state before telling them what you want.

The following code examples do not break Tell Don't Ask:

if ( foo.isInStateA() )
   bar.setStateB();

if ( foo.isInStateA() )
   this.setStateB();


0
daniel_t (1960)
2/15/2007 3:43:01 PM
On 15 Feb, 15:43, "Daniel T." <danie...@earthlink.net> wrote:
> On Feb 11, 9:09 pm, Frank Fredstone <n...@not.no> wrote:
>
>
>
>
>
> > I'm still struggling with OO concepts. I've read several books and
> > studied various OO languages, but I don't really feel I have a good
> > grasp of the concepts.
>
> > I like the sound of the "tell, don't ask" model, where networks of
> > objects are asked to perform the work they are responsible for, rather
> > than asking objects to give you information (like a string) that you
> > do something with. But, I get confused when I try to apply the idea to
> > a program design.
>
> > The only way I can think of avoiding asking objecs for information is
> > if the program consists of nothing but one object of class "Program"
> > with one method called "execute" that does everything.
>
> > I've seen an example of bad design:
>
> > AssociativeArray c = object.getEmployees()
> > for each employee in employees:
> >         c.put(employee.name(), employee)
>
> > the "tell don't ask" version of which could be:
>
> > object.addEmployees(employees);
>
> > So, "object"'s class supports the "tell model", by allowing you to
> > tell it to add employees rather than asking it for a map to modify.
>
> > But, doesn't that mean that "employees"'s class has to support the
> > "ask model", so that it "object" can get each of the "employee" objects and
> > their names?
>
> > Is there a way to actually use "tell" insead of "ask", through
> > out. Or, how do you categorize when you should use "tell" and when you
> > should use "ask"?
>
> I get the impression that there is some confusion here between "tell,
> don't ask" and the Law of Demeter. Your code example breaks the
> latter, not the former. An example that breaks the former would be
> something like:
>
> if ( someObject.isInStateFoo() )
>    someObject.setStateBar();
>
> IOW, breaking tell don't ask means you shouldn't have to ask them
> about their state before telling them what you want.
>
> The following code examples do not break Tell Don't Ask:
>
> if ( foo.isInStateA() )
>    bar.setStateB();
>
> if ( foo.isInStateA() )
>    this.setStateB();- Hide quoted text -
>
> - Show quoted text -

This would also coincide with my interpretation.....I thought maybe I
was the one who was out of step.

I'm not a great fan of the 'Law of Demeter'.

0
Nicholls.Mark (1061)
2/15/2007 4:28:05 PM
Frank Fredstone wrote:
> I'm still struggling with OO concepts. I've read several books and
> studied various OO languages, but I don't really feel I have a good
> grasp of the concepts.
> 
> I like the sound of the "tell, don't ask" model, where networks of
> objects are asked to perform the work they are responsible for, rather
> than asking objects to give you information (like a string) that you
> do something with. But, I get confused when I try to apply the idea to
> a program design.
> 
> The only way I can think of avoiding asking objecs for information is
> if the program consists of nothing but one object of class "Program"
> with one method called "execute" that does everything.

If you want to see a good larger example of "tell don't ask" in action, 
take a look at the 3.8.1 version of the JUnit testing framework.  In it, 
you create subclasses of a class named TestCase and bundle them up in a 
TestSuite.  You tell the TestSuite to run, and it tells each test to 
execute.  Each test tells a TestResult to run it and the TestResult 
tells any listeners and the results.  It's "tell" all the way along.

"Tell, Don't Ask" doesn't have to lead to a single large object.  You 
can delegate responsibilities across a set of objects and have them to 
do the work for you.

----
Michael Feathers
www.objectmentor.com
michaelfeathers.typepad.com
author of: Working Effectively with Legacy Code (Prentice Hall 2005)
0
mfeathers2 (74)
2/20/2007 1:47:35 PM
"Daniel T." <daniel_t@earthlink.net> writes:

> On Feb 11, 9:09 pm, Frank Fredstone <n...@not.no> wrote:
>> I'm still struggling with OO concepts. I've read several books and
>> studied various OO languages, but I don't really feel I have a good
>> grasp of the concepts.
>>
>> I like the sound of the "tell, don't ask" model, where networks of
>> objects are asked to perform the work they are responsible for, rather
>> than asking objects to give you information (like a string) that you
>> do something with. But, I get confused when I try to apply the idea to
>> a program design.
>>
>> The only way I can think of avoiding asking objecs for information is
>> if the program consists of nothing but one object of class "Program"
>> with one method called "execute" that does everything.
>>
>> I've seen an example of bad design:
>>
>> AssociativeArray c = object.getEmployees()
>> for each employee in employees:
>>         c.put(employee.name(), employee)
>>
>> the "tell don't ask" version of which could be:
>>
>> object.addEmployees(employees);
>>
>> So, "object"'s class supports the "tell model", by allowing you to
>> tell it to add employees rather than asking it for a map to modify.
>>
>> But, doesn't that mean that "employees"'s class has to support the
>> "ask model", so that it "object" can get each of the "employee" objects and
>> their names?
>>
>> Is there a way to actually use "tell" insead of "ask", through
>> out. Or, how do you categorize when you should use "tell" and when you
>> should use "ask"?
>
> I get the impression that there is some confusion here between "tell,
> don't ask" and the Law of Demeter. Your code example breaks the
> latter, not the former. An example that breaks the former would be
> something like:
>
> if ( someObject.isInStateFoo() )
>    someObject.setStateBar();
>
> IOW, breaking tell don't ask means you shouldn't have to ask them
> about their state before telling them what you want.
>
> The following code examples do not break Tell Don't Ask:
>
> if ( foo.isInStateA() )
>    bar.setStateB();
>
> if ( foo.isInStateA() )
>    this.setStateB();

The definition of tell don't ask I'm using is from this article:

http://www.pragmaticprogrammer.com/ppllc/papers/1998_05.html

and references to that interpretation of telling instead of asking in
various things I read while looking into testing using mock objects.

The point of indicating where I got the definition is only to clarify what
my question is.

I am still confused by the example in the above article, since the
resolution seems to simply be shifting where you "ask" from one class
to another. So, how do you decide when it's beneficial to use "tell"
instead of "ask" and when it's beneficial to use the opposite?

Aside from the ideas that bumbing up against a procedural boundary in
interacting with some procedural system such as an OS, could make it
necessary to create a class that is designed to be "asked" for some
data, and aside from the idea that a "dumb data object" (e.g. Point)
might best be designed to be "asked", I don't really have any
guidelines that are allowing me to grasp the issue clearly. I suppose
I will just have to discover it for myself.
0
none90 (22)
2/21/2007 5:43:58 PM
Reply:

Similar Artilces:

Don't ask, don't tell...
While my son visited me for the day, after we went to the Hawks-Giants game and then to see Harry Potter he was still awake (12 years old) and so I put him in front of my Suse 10.0 machine and let him play Unreal Tournament 2004 in Linux. I let him set up the machine in Control Center first (he's a right hander and I'm a leftie), using KDE Control center, and then had him launch and run UT2004. I did't say anything about this being a Linux machine and I have no idea if he knows what Linux is even. I was about to "give the speech about Linux" and I decided, no, I would just let him use the machine and see what he said. He said nothing. He just used the machine as a PC, made the changes, launched an app and played UT04. To me that speaks volumes. That a new user to Linux, who's never seen it in his life, did not perk up and say "oh, what's this! is it some new kind of computer!". No, it was just another GUI, that allowed him to do the task that he wanted to. And that means that there is nothing stopping Linux. John Bailo wrote: > While my son visited me for the day, after we went to the Hawks-Giants game > and then to see Harry Potter he was still awake (12 years old) and so I put > him in front of my Suse 10.0 machine and let him play Unreal Tournament > 2004 in Linux. I let him set up the machine in Control Center first (he's > a right hander and I'm a leftie), using KDE Control center, an...

AOL 9.0 don't do it just don't . Don't even think of it.
I had 8.0, and it ran fine. I downloaded 9.0 and that was the end of my computer never having a problem. 3 years and no problems. 1 week with AOL 9.0 and I've had 27 error messages , sign offs and other problems. AOL was no help. They can't even admit it has a problem. So I had to REFORMAT MY HARD DRIVE AND INSTALL ALL MY PROGRAMS AND ALL MY SAVED FILES. Needless to say I no longer have AOL at all. Reformat and get rid of it. ...

I sell various items for Amiga on EBAY, if you don't agree don't read and don't break my balls, understand mr. user?
See on this link: http://search.ebay.it/_W0QQsassZmousemikiQQhtZ-1 P.s. not all items are for Amiga, simple don't see others! ...

Linux crapware victim: Mepis8 'collapsed'... webcams don't work on Ubuntu 12.04..."Don't tell me to build a kernel..."
"I need my webcam to work with flash on web pages so that I can speak to family members overseas (Kopete and suchlike). I used mepis8 for years and everything was perfect, my webcams (three different makes), printers and anything else I cared to plug in worked from the off. lovely!! Then mepis8 collapsed suddenly and nothing worked. I tried the newer mepis variants and every other linux distro that I came across to solve the problem, but nothing works. I'm now using ubuntu 12.04, because it's not windows I suppose, but it's far from what I need. Can anybody on here please tell me how to make any one of my webcams work on Ubuntu 12.04 with flash? Don't tell me it's the manufacturer's fault, because they worked on Mepis8. Don't tell me to build a kernel and add some Su (or do or sudo) and add a line et al because it's all gibberish to me. Keep it simple please. Complicated is fine as long as it's step by step or copy and paste. Unfortunately, after about 12 years on linux, I will be driven back to windows if I don't get some help. The Mepis forums used to be excellent for advice because there weren't any bigheads showing off their superior knowledge of linux on it. The Ubuntu forums seem to be the opposite, more than 1000 posts (in two threads) on why they prefer ubuntu to xp, but none of them can help me get my webcam working!!!! So this is the challenge, before ...

I don't work for IBM and I don't make promises I can't deliver on
I wish I could afford an advertising campaign to compete with what they have on the Internet now. I promise to go totally ballistic at the next LLLNL contract. Robert. On 8/12/2011 11:24 PM, Robert Myers wrote: > I wish I could afford an advertising campaign to compete with what they > have on the Internet now. > > I promise to go totally ballistic at the next LLLNL contract. > > Robert. I don't work for IBM (anymore) either. If you are talking about the death of Blue Waters, I don't believe they said they couldn't deliver. They said they chose not to because they would lose a bunch of money on the project since it turned out to cost a lot more than the initial guess. And I guess Ben chose not to print some more to pay for it. On Aug 24, 11:17=A0pm, Del Cecchi <delcec...@gmail.com> wrote: > On 8/12/2011 11:24 PM, Robert Myers wrote: > > > I wish I could afford an advertising campaign to compete with what they > > have on the Internet now. > > > I promise to go totally ballistic at the next LLLNL contract. > > > Robert. > > I don't work for IBM (anymore) either. =A0If you are talking about the > death of Blue Waters, I don't believe they said they couldn't deliver. > They said they chose not to because they would lose a bunch of money on > the project since it turned out to cost a lot more than the initial guess= .. > > And I guess Ben chose not to print some mor...

'don't ask,tell' speration of concerns
(although it was posted in a spring forum, for it's special usage, i felt it may need larger mind meld for this design question). i keep reading in mock artible how one should not use getters for objetcs like for example instead of dog.getBody.getTail(); one should do dog.wagTheTail however it occurs to me this the is a wrong seperation of concerns here, becouse as i see it, you have a division of model beans (dog,body etc..) and a division of services performing actions on said beans, such services, that are maybe created by spring, and that wagTheTail method should actually belong...

Lotus Notes: Don't Pass, Don't Pay! That's our Certification Guarantee.
Study with CertFX, the leader in Lotus, WebSphere and WebSphere Portal Certification practice tests. With CertFX practice tests, all purchases are available for immediate download. You also receive free support, lifetime maintenance and real-time updates with your purchase. CertFX has all Domino 8, WebSphere and WebSphere Portal practice tests available. We are fanatical about updating our content to ensure we provide you with the best, most accurate study materials on the market. Get started on your recertification today by visiting: http://www.dominonews.com/homepage.nsf...

Lotus Notes: Don't Pass, Don't Pay! That's our Certification Guarantee.
Study with CertFX, the leader in Lotus, WebSphere and WebSphere Portal Certification practice tests. With CertFX practice tests, all purchases are available for immediate download. You also receive free support, lifetime maintenance and real-time updates with your purchase. CertFX has all Domino 8, WebSphere and WebSphere Portal practice tests available. We are fanatical about updating our content to ensure we provide you with the best, most accurate study materials on the market. Get started on your recertification today by visiting: http://www.dominonews.com/homepage.nsf...

Don't Call. Don't Write. Let Me Be.
YOUR MONEY Don't Call. Don't Write. Let Me Be. By DAMON DARLIN The fears of the direct marketing industry came true. Once a do-not-call list was created, people did register, in droves. The list was created in 2003, not as a way to protect privacy, but to remove a powerful irritant from the lives of Americans. The Federal Trade Commission, which administers the list, says that more than 137 million phone numbers have been placed on the list by people tired of interruptions during dinner or their favorite TV show. The popularity of the do-not-call list unleashed a demand for other opt-out lists. A consumer can now opt out of the standard practice of their banks or loan companies selling their information to others. Other opt-outs stop credit card companies from soliciting consumers or end the flow of junk mail and catalogs. While most of the opt-outs are intended to make life less annoying, they can also have the side effect of protecting personal information that can be misused by identity thieves or unscrupulous merchants. http://www.nytimes.com/2007/01/20/business/20money.html?ex=1326949200&en=3efc9e8515a9ea4a&ei=5090 ...

Don't like MSIE6? Don't like MS?
If you so dislike MS, do the minimal thing: advocate another browser on web pages you control. Example: http://masonc.home.netcom.com This is not a troll. Just go do what you're told and shut up. Mason C I will not respond Mason A. Clark wrote: > If you so dislike MS, do the minimal thing: advocate another > browser on web pages you control. > > Example: http://masonc.home.netcom.com > > This is not a troll. Just go do what you're told and shut up. > > Mason C I will not respond I don't advocate ...

Apples don't fall from the tree, don't you know
Apples don't fall from the tree, don't you know? On 3/23/2015 9:23 AM, John Gohde wrote: > Apples don't fall from the tree, don't you know? No, I don't know that. Nobody but you knows that, GodHesDumb. ..Apples don't fall FAR from the tree, don't you know? > > No, I don't know that. Nobody but you knows that LOL - In DooF..uS' case, they surely float up. On 23/03/2015 13:23, John Gohde wrote: > Apples don't fall from the tree, don't you know? > You might want to carefully read what you wrote unles...

Don't you feel bad when you don't finish up a game??
I own a lot of games that I did not finish. Most current let downs are deus ex 2 and warcraft 3 expansion. I always feel that it is my fault that i dont finish the games. The reason: I lost interest because 1)another cool game came out and bought it and lost interest in the old one or 2) The game sucks (aka deus ex 2) or 3) to hard to finish. Somehow I feel bad altough most of the times I shall not since the designers f***ed the product this time around. Do you guys feel the same way???? Of course you might say that i could wait until I read all the reviews, played the demo amd read t...

Re: Don't Call. Don't Write. Let Me Be.
Monty Solomon wrote: > YOUR MONEY > Don't Call. Don't Write. Let Me Be. > By DAMON DARLIN > The fears of the direct marketing industry came true. Once a > do-not-call list was created, people did register, in droves. Unfortunately, there are too many exceptions. Non-profit organizations and politicians can still make unwanted soliciting calls and they do so in droves. Past contacts may call as well, and "past contact" is a very loose definition. Some callers simply disregard the law, knowing they'll get away with it. ...

Re: Don't Call. Don't Write. Let Me Be. #3
On Jan 22, 1:01 pm, DevilsPGD <spam_narf_s...@crazyhat.net> wrote: > In message <telecom26.22...@telecom-digest.org>: > Not so much that they get away with it, paying the fines is just a > cost of business. The vast, vast majority of the consumers will not go to the trouble of carefully tracking and reporting illegal solicitation calls. So the solicitors never get into trouble in the first place and thus there is no fine. They use techniques that mask their caller-ID. VOIP carrier?. "Fly-by-night" long distance carrier that simply doesn't pass along the data? Even if a consumer does report a complaint, the authorities only act upon receiving a great many complaints that are solidly substantiated. Again, the chance that will happen is very small. It was a common trick in the old days for scammers to rent a storefront and fake a busy business, do their thing for a few months, then take off before the victims and authorities could react. By the time they do, they only find an empty store, the criminals are long gone. In the modern world, it's a lot easier, no physical property (and expense) is required. Just create a website or telephone carrier, which thanks to deregulation and our beloved "open world*" is very easy to do. Remember the problem with illegal long distance carrier switching? *See Pat's comments on this in a separate post issued today. In my opinion, the problems we ha...

Re: Don't Call. Don't Write. Let Me Be. #2
In message <telecom26.22.10@telecom-digest.org> hancock4@bbs.cpcn.com wrote: > Some callers simply disregard the law, knowing they'll get away with it. Not so much that they get away with it, paying the fines is just a cost of business. 'Tis far better to have snipped too much than to never have snipped at all. [TELECOM Digest Editor's Note: The fines should increase each time they are imposed until the company could no longer afford the cost. PAT] ...

OS X
after a bit of reading, it looks like I did a veeeeery shtupid thing... (I'm copying my post to this newsgroup, as the alt.sys.mac.newuser-help group didn't look quite as highly-trafficked...) anyways, here's what I did... ----------------------------------- in an effort to help the owner of a nice shiny new eMac 'clean up' their personal folder, I moved a few items... including the Library folder! it appears.... correct me if I'm wrong... that Mac OS X then created a NEW library... so we restarted it, and all the Quicken data, dialup info, (etc.) was gone... so we ...

OT: Too funny not to share (DON'T READ THIS IF YOU DON'T HAVE A SENSE OF HUMOR)
Dear Abby, My husband is a liar and a cheat. He has cheated on me from the beginning; and, when I confront him, he denies everything. What's worse, everyone knows=20 that he cheats on me. It is so humiliating! Also, since he lost his job six years ago, he hasn't even looked for a new one. All he does all day is smoke cigars, cruise around and shoot the bull with his buddies, while I have to=20 work to pay the bills. And since our daughter went away to college, he doesn't even pretend to like me and hints that I may be a lesbian. What should I do? Signed,...

I don't see why the pipe program doesn't show up on ps when it 'hangs'
I commented out the waitpid() in the following pipe program.. [cdalten@localhost oakland]$ more pip3.c #include <sys/types.h> #include <sys/wait.h> #include <unistd.h> #include <stdlib.h> #include <stdio.h> int main(void) { pid_t pid; char line[BUFSIZ]; int fd[2]; char string[] = "hello world\n"; ssize_t n; if (pipe(fd) < 0) { fprintf(stderr, "pipe error\n"); exit(EXIT_FAILURE); } if ((pid=fork()) < 0) { fprintf(stderr, "fork error\n"); } else if (pid > 0) { close(fd[0]); printf(&qu...

I don't get why '>' doesn't get printed in the following example
When I do a here-document, the '>' character shows up to indicate the start of a newline. [cdalten@localhost ~]$ cat << EOF > My current directory is dir $PWD > EOF My current directory is dir /home/cdalten [cdalten@localhost ~]$ What prevents the '>' characters from showing up in the final output? On Jul 3, 10:35 am, Chad <cdal...@gmail.com> wrote: > When I do a here-document, the '>' character shows up to indicate the > start of a newline. > > [cdalten@localhost ~]$ cat << EOF> My current directory is dir $PWD > &...

I don't read docs and don't know how to use Google. What does the print function do?
Please help me this assignment is due in an hour. Don't give me hints, just give me the answer because I only want a grade. I'm not actually interested in learning how to program, but I know software engineers make lots of money so I want to be one. sohcahtoa82@gmail.com wrote: > Please help me this assignment is due in an hour. Don't give me hints, > just give me the answer because I only want a grade. I'm not actually > interested in learning how to program, but I know software engineers make > lots of money so I want to be one. I'm sorry I have...

GUI question
I am writing an application with multiple windows. I want the main window to open first. Then I want the user to be able to interact with this main window (via uicontrols). I want plots to be drawn in this main window, etc. Sometimes dialogs and other windows will be opened, but the main window should always remain open. I think this is the default behavior... When I try to run my program, the figure's OpeningFcn is called, initialize_gui is called, the main gui window is created and displayed and my uicontrols work. But, rmappdata in gui_mainfcn is immediately called and the handle to my...

Oh damn. A free Trojan and I don't get to enjoy it because I don't run Windows.
I just received this message in my email not too long ago. Quoted message below " v> Hello friend ! You have just received a postcard from someone who cares about you! This is a part of the message: "Hy there! It has been a long time since I haven't heared about you! I've just found out about this service from Claire, a friend of mine who also told me that..." If you'd like to see the rest of the message ->click here<- to receive your animated postcard! =================== Thank you for using www.yourpostcard.com 's services !!! Please take this op...

Don't understand: when('foo' and/or 'bar')
Would someone be so kind to explain the following (quotes are for win32 perl): perl -E" $u='foo'; given($u){ when('foo' and 'bar'){say 'f'} default{say 'd'} } " d perl -E" $u='bar'; given($u){ when('foo' and 'bar'){say 'f'} default{say 'd'} } " f perl -E" $u='baz'; given($u){ when('foo' and 'bar'){say 'f'} default{say 'd'} } " d perl -E" $u='foo'; given($u){ when('foo' or 'bar'){say 'f'} default{...

I don't mind Linux. It's the fan club I can't stand.
Linux: A sheer waste of processing time. On Thu, 09 Feb 2006 23:42:08 -0500, Ana Thema wrote: > Linux: A sheer waste of processing time. Ana Thema ... a witch in search of batteries... -- Rick <http://ricks-place.tripod.com/sound/2cents.wav> In comp.os.linux.advocacy, Ana Thema <anathema@gmail.net> wrote on Thu, 09 Feb 2006 23:42:08 -0500 <o96ou15hrlhepdpdr7pkbefq3ep4e31ve1@ax4.com>: > Linux: A sheer waste of processing time. > Well of course it is; everyone should just use Windows instead. The occasional hangs, glitches, and crashes are more than compensa...

Web resources about - don't tell don't ask - comp.object

Resources last updated: 3/14/2016 2:22:34 AM