TE
TechEcho
Home24h TopNewestBestAskShowJobs
GitHubTwitter
Home

TechEcho

A tech news platform built with Next.js, providing global tech news and discussions.

GitHubTwitter

Home

HomeNewestBestAskShowJobs

Resources

HackerNews APIOriginal HackerNewsNext.js

© 2025 TechEcho. All rights reserved.

Tell, don't ask

216 pointsby djacobsalmost 13 years ago

23 comments

bluesnowmonkeyalmost 13 years ago
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.<p><pre><code> 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 </code></pre> 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.<p>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.
评论 #4268524 未加载
评论 #4268439 未加载
评论 #4268451 未加载
djacobsalmost 13 years ago
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.<p>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.
评论 #4268323 未加载
评论 #4268554 未加载
评论 #4268257 未加载
评论 #4268338 未加载
afrenchcoderalmost 13 years ago
all of those examples look horrible, make debugging harder and implies strong code coupling.<p>example 1, we're mixing data with UI labels. How do you handle localization ? by coupling your localization code with your user data/behavior ?<p>example 2 : you're simply coupling the system_monitor with the alarm, while in the worst case, the alarm should be linked to the system_monitor. Now if you want to add a "report_to_government_agency" method, you'd add that inside the code of every single one of your monitors (knowing that you don't want to report a broken light, but it might be a good idea for a melting nuclear core) ? Note that I'm not saying that the first code is good, it's just as bad... Also, the method becomes very poorly named (I want to know if the sensor went back to normal, but every time I query "check_for_overheating", it just rings the alarm and doesn't give me any info back ???)<p>example 3 is just a poor usage of pseudo inheritance (and an abuse of duck typing). you create a new type of user for every messaging service again ? and if a user uses more than one messaging service, you just create a type for every combination ? Not very scalable nor readable, IMO.<p>The last example is just as bad. useless inheritance, senseless object. the definition of street_name is wrong. the doc will be around "Street name returns a street name or an error message if there's no street name defined" How do you know if there's no street name, now ?<p>All those examples basically make all extension harder. They're everything that's wrong with OO. an object is not about one structure that contains data and does everything that can be done with it. An object is about giving organized access to pertinent data and/or pertinent behavior and (potentially) allowing to change them.
fusiongyroalmost 13 years ago
This is a great little refresher. I recently inherited a codebase of about 3500 lines, 2500 of which are in one class. Not OO.<p>Incidentally, if this article blew your mind or if you're interested in Smalltalk, I can't recommend this book enough:<p><a href="http://www.lulu.com/shop/andres-valloud/a-mentoring-course-on-smalltalk/paperback/product-3788890.html" rel="nofollow">http://www.lulu.com/shop/andres-valloud/a-mentoring-course-o...</a><p>The author has a radical take on OO in Smalltalk and shows that going to absurd lengths to eliminate if-statements (well, ifTrue: et. al., because it's Smalltalk) can lead to both better readability and better performance.
0x0almost 13 years ago
Going down this path seems to put your code at risk for dangerous mixing of concerns, in some cases.<p>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.
评论 #4268239 未加载
ricardobeatalmost 13 years ago
Disclaimer: not a Ruby user. I'm confused by example 4. Why would you return a message from either of them? Shouldn't messages in general belong to the view?<p><pre><code> {{ user.address || "No address on file" }} </code></pre> The "not so good" code is essentially this, but inside a wrapper in view code. What if you need different markup for a missing address, you either stuff it into a method or change the method's return value to nil... and what if only <i>street_name</i> is missing, not the whole address? It looks like a big mess to me.
评论 #4269360 未加载
lincolnqalmost 13 years ago
Makes some good points. I can't help but notice, though, that the "good" examples are all <i>longer</i>.<p>It makes me want to design a programming language that makes good code shorter than bad code...
评论 #4269626 未加载
n72almost 13 years ago
Ick, breaks command/query separation, the other OO rule that along with tell, don't ask I find to be a hallmark of well coded OO systems.<p>class SystemMonitor def check_for_overheating if temperature &#62; 100 sound_alarms end end end
zwiebackalmost 13 years ago
Also see <a href="http://c2.com/cgi/wiki?TellDontAsk" rel="nofollow">http://c2.com/cgi/wiki?TellDontAsk</a>
sukuriantalmost 13 years ago
This has long been one of my favorite methods of using OO code to my advantage; and is one of the main reasons that my code is OO in the first place.<p>There are many cases where it's easier/lazier to have if-statements.<p>Going further, you can take the things learned in this article to make your general purpose code potentially faster, as well. For example, if a set of things that must be performed in order; and sometimes some of those steps are missing, instead of performing a null-check, you can have a default no-op case; that way, instead of:<p><pre><code> if(firstAction != null) firstAction(); if(secondAction != null) secondAction(); if(thirdAction != null) thirdAction(); </code></pre> in your inner loop, you can have:<p><pre><code> firstAction(); secondAction(); thirdAction(); </code></pre> While whenever firstAction, secondAction, thirdAction are set, you can say:<p><pre><code> firstAction = newFirstAction ?? noop; // etc. </code></pre> All in all, I'm glad this sort of knowledge is getting out there. I'm just grateful for my having really, really good CS teachers back in highschool ( I don't remember my college talking about OO as a way of removing if-statements ).<p>* Users of Java, of course, will just need to write a NoOp instance of their interface to take advantage of this.
评论 #4269121 未加载
jawralmost 13 years ago
I liked the first example, but then it felt too preachy; OOP isn't necessarily the correct way to do things.<p>I really like the clean design of the site though, very fresh imo.
ninetaxalmost 13 years ago
Awesome! This is think kind of article I love to see on HN.
InclinedPlanealmost 13 years ago
Refactoring: <a href="http://www.amazon.com/Refactoring-Improving-Design-Existing-Code/dp/0201485672/" rel="nofollow">http://www.amazon.com/Refactoring-Improving-Design-Existing-...</a><p>Read it. Learn it. Love it. Make it a habit that is so ingrained you do it automatically.<p>Extract method: do it reflexively.
edoloughlinalmost 13 years ago
I'm not trying to be elitist or superior, but I can't understand why this has spent such a long time on the front page. Shouldn't the content of the article be considered pretty basic knowledge at this stage of OO? Deferring implementation specifics using polymorphism was one of the first things I learned about OO when I was introduced to it (via C++) around 1992. It was definitely 'aha' worthy then, when the vast majority of commercial development was procedural, but these days? Shouldn't it be considered a basic tool in most devs' repertoire?
评论 #4270125 未加载
omgseanalmost 13 years ago
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.
MaxGabrielalmost 13 years ago
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?
评论 #4268258 未加载
评论 #4268255 未加载
gavalmost 13 years ago
The first example isn't a good one. You don't want to have the user class responsible for returning the welcome message.
unconedalmost 13 years ago
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.
评论 #4268309 未加载
评论 #4268690 未加载
n72almost 13 years ago
Relatedly, a long, long time ago I found Allan Holub's PPT Everything You Know is Wrong quite good: <a href="http://ebookbrowse.com/everything-you-know-is-wrong-pdf-d281291032" rel="nofollow">http://ebookbrowse.com/everything-you-know-is-wrong-pdf-d281...</a>
Killswitchalmost 13 years ago
Wow, short article, but huge impact... I'm gonna start doing this... Makes so much more sense. Thank you.
robotmentalmost 13 years ago
The example is too simple to describe this design.
keymonealmost 13 years ago
examples could be much better..
tbrownawalmost 13 years ago
This principle applies much more broadly than just to programming with objects, for example it's an excellent way to deal with bureaucracies or managers who don't always read their email.