Live data from Hacker News

Tell, don't ask

robots.thoughtbot.com

11–20 of 88 posts

Re: Tell, don't ask

#11
For me, this technique is bigger than objects or encapsulation. It's about reusing existing "branch points" that a language gives you (whether it is polymorphism, method dispatch, namespacing) instead of explicit conditionals at a level higher than the language. My general take is that explicit conditionals in a high-level language are a smell. Sometimes they're necessary, but if you tell yourself that they mostly aren't, you tend to end up with cleaner code.

I'm not saying it's possible to avoid conditionals completely, but this article gives several good examples of where it's possible. Someone should put together a similar set of examples in a functional language.

Re: Tell, don't ask

#12
post #10
post #5

Going down this path seems to put your code at risk for dangerous mixing of concerns, in some cases. Unit-testing the check_for_overheating inside SystemMonitor looks complicated... The "sound_alarms" call inside probably needs to be a reference to a "Speaker.sound_alarms", right? Why should the SystemMonitor be locked to the API of a Speaker? etc.

The 'sound_alarms' call looks more like a local method to me, which could invoke the speaker in a loosely coupled fashion. The point is more about putting the behavior itself in the object. For unit testing, you'd want to move the individual tests into their own classes, letting the SystemMonitor be the glue that calls them and routes responses to the appropriate system.

Your second sentence pretty much hit the nail on the head, as I was reading your first: I'd create a different "controller" object that glues the SystemMonitor and the Speakers together. Then you'd have the neat little "tell, don't ask" in THAT object, instead. (Pretty much what you suggested)

Re: Tell, don't ask

#13

Cool, I haven't heard of this before; I will think about it. Presumably, an exception would be 'view' type objects in an MVC setup?

I apply this principle to view objects as well. Can you give an example of something you think should be excepted?

Re: Tell, don't ask

#14
post #11

For me, this technique is bigger than objects or encapsulation. It's about reusing existing "branch points" that a language gives you (whether it is polymorphism, method dispatch, namespacing) instead of explicit conditionals at a level higher than the language. My general take is that explicit conditionals in a high-level language are a smell. Sometimes they're necessary, but if you tell yourself that they mostly ar…

To a certain level this is true. However if you hide all branching logic inside OO techniques, following the flow of logic and decisions becomes harder as they are hidden in deeply nested class hierarchies and overridden functions.

Re: Tell, don't ask

#15

Cool, I haven't heard of this before; I will think about it. Presumably, an exception would be 'view' type objects in an MVC setup?

Yes and no, the approach I've used in MVC (.Net) is passing View Models to the View (rather than pure models). That means you can push some of the "tell" into the view model rather than having that logic in the view itself.

I haven't done any RoR but I imagine a similar approach would work there.

Re: Tell, don't ask

#16
If you're interested in this kind of thing I highly recommend Avdi's Objects on Rails book (it's free) and Destroy All Software's screencast collection.

Re: Tell, don't ask

#17
post #8

Excellent. As a self-taught hacker, I always felt like I was missing something about OO, because it's introduced with an analogy to real world objects, while glossing over the more subtle contracts that programming objects have with each other. Seems like we need a more developed vocabulary to express these things.

I first heard "Tell don't ask" in relation to Smalltalk.

If you want a developed vocabulary, Smalltalk is where you find it (and it's been there for thirty-odd years).

Re: Tell, don't ask

#18
post #11

For me, this technique is bigger than objects or encapsulation. It's about reusing existing "branch points" that a language gives you (whether it is polymorphism, method dispatch, namespacing) instead of explicit conditionals at a level higher than the language. My general take is that explicit conditionals in a high-level language are a smell. Sometimes they're necessary, but if you tell yourself that they mostly ar…

Personally, I think this is what 'encapsulation' is about. People have generally thought about 'encapsulation' as guarding the data but I feel that it is about both data + behavior.

A quick tip: Any time you check an object's state to decide which method to call on it, you are breaking encapsulation. Call the method on the object and let it figure out what to do based on the state it is in.

Re: Tell, don't ask

#19
Example 3 adds a nonsense method, EmailUser#send_to_feed. What does that mean? Email users don't have feeds. If we're going to evangelize OO purity, let's do it right.

    class Post
      def created
        user.post_created(self)
      end

      def send_to_feed(feed)
        feed.send(contents)
      end
    end

    class TwitterUser
      def post_created(post)
        post.send_to_feed(twitter)
      end
    end

    class EmailUser
      def post_created(post)
        # no-op.
      end
    end
The post merely tells its user that it was created. Then the user can decide to do something else. All users know about posts, but only TwitterUser knows about feeds.

Honestly though, if I saw the not-so-good code, I'd leave it alone. It takes a pretty big justification to double the code for the same features.

Re: Tell, don't ask

#20
post #11

For me, this technique is bigger than objects or encapsulation. It's about reusing existing "branch points" that a language gives you (whether it is polymorphism, method dispatch, namespacing) instead of explicit conditionals at a level higher than the language. My general take is that explicit conditionals in a high-level language are a smell. Sometimes they're necessary, but if you tell yourself that they mostly ar…

> I'm not saying it's possible to avoid conditionals completely

But it is. Smalltalk has no conditional statement, conditionals are implemented via polymorphism on the subclasses True and False (ignoring compiler optimizations).

Post reply on HN