Re: don't tell don't ask
- From: "H. S. Lahman" <h.lahman@xxxxxxxxxxx>
- Date: Mon, 12 Feb 2007 19:39:25 GMT
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@xxxxxxxxxxxxxxxxx
Pathfinder Solutions
http://www.pathfindermda.com
blog: http://pathfinderpeople.blogs.com/hslahman
"Model-Based Translation: The Next Step in Agile Development". Email
info@xxxxxxxxxxxxxxxxx for your copy.
Pathfinder is hiring: http://www.pathfindermda.com/about_us/careers_pos3.php.
(888)OOA-PATH
.
- References:
- don't tell don't ask
- From: Frank Fredstone
- don't tell don't ask
- Prev by Date: Re: Passing a lot of parameters in constructor?
- Next by Date: Re: Passing a lot of parameters in constructor?
- Previous by thread: Re: don't tell don't ask
- Next by thread: Re: don't tell don't ask
- Index(es):
Relevant Pages
|