Design patterns and OOP have their place, but this article adheres to them too dogmatically for my taste. It reminds me a little of this:
http://steve-yegge.blogspot.com/2006/03/execution-in-kingdom...
When I first started programming, I wanted a set of rules which, if followed strictly, would always guide me towards the perfect architecture. I've since learned that such a set of rules doesn't exist. Instead, we have to rely on our experience and insight to tell us which architecture will solve a given problem elegantly, and which will shoot us in the foot.
The OOP absolutists seem to be looking for that same El Dorado I once wanted. Ostensibly, design patterns promise us programming bliss through tried-and-true, universally applicable architectures. But they don't. Oftentimes, they just give you more lines of code than you really need.
It sounds like I'm dumping on OOP and design patterns, but I'm not. Like I said, there are plenty of perfectly good applications for them. My point is that it takes a bit of that aforementioned experience and insight to recognize those instances when they're appropriate. Otherwise you're just painting by numbers.
All I can say is, if I worked in a Rails shop and checked some code in that used a helper to generate the A-Z index of a collection of models, and my boss told me, "no, you need to move that code to app/presenters/as_dictionary.rb, because that's where I've been putting my code that presents our data as_numbered_lists and as_abbreviated_snippets and as_random_selectons; it's called the Presenter pattern and we use it", I'd look for new projects.
Also, "structured programming" isn't "Programming 1.0" to "object oriented programming"'s "Programming 2.0". That is not how it works, Steve.
I'm not defending these exact examples or anything, but come on. Any kid out of school can toss some code into a project that just works. It takes some discipline to write reusable code that people know where to look for later.
In the case of Rails, it's a framework and the patterns of that framework are established. I know to look for models in the models directory, controllers in the controllers directory, and helpers in the helpers directory. When I come into someone else's project, it's nice to know where things are. I've inherited lots of code from consultants who know "best practices" and move from one project to the next. Some of these projects barely resemble Rails anymore.
It's led me to ask the question "If Rails isn't good enough, then why are you using it?"
But this post should have been the original blog post. You can't get frustrated by your audience "not getting it" if you use terrible examples or if you're lying to simplify.
This was a good explanation on the way to use presenters. The original one was not. I still don't plan to run out and use presenters everywhere because the payoff simply isn't there for most of the apps I write.
My bigger concern is that, like with most things in Ruby, a certain percentage of folks are going to just run wild with an idea, and even the simplest application is going to have a bunch of presenters in it just because someone said it was "the right way".
It's good to explain the real "why" with these concepts. What are the benefits, the drawbacks, and what will I be able to do that I couldn't do before? So I think this followup does a great job of that.
With a blog post, you can revise the original based on feedback, but the odds are that none of the people who read it the first time will see the revision. A follow-up post is the best way to expand/expound/correct yourself.
I agree that the first post could have been even better, but given the first post being what it was, putting out a second post seems like the right thing to do.
That said, I do appreciate Steve's work on finding ways outside of "the one true path" to simplify Ruby code, and hope he'll continue writing these sorts of things going forward. If nothing else, the discussion surrounding the technique and it's alternatives is extremely worthwhile.
" ... functions don’t provide a sufficient amount of power to tackle hard problems."
" objects > functions"
Why start an otherwise well written post with such trollish statements?
There's a lot more substance in the following paragraphs but instead everyone is focusing on those.
Your homework is to spend three months with Haskell learning idiomatic Haskell. Yes, it's not OO. Suck it up. You won't truly understand OO until you also understand not-OO.
I completely agree that one should write idiomatic code. When you write Haskell, you write idiomatic Haskell. When you write Ruby, you should write idiomatic Ruby. Objects are idiomatic Ruby.
The code Steve suggests here would be more idiomatic in Java than in Ruby. That's what this reminds me of — Java's endless array of classes-that-want-to-be-functions. Next somebody's going to realize that you might want to present dictionaries in different ways, so obviously you're going to want a DictionaryPresenterFactory to create a DictionaryPresenter to your specifications (because just having a method with that functionality would not be sufficiently OO, obviously).
I think Norvig's presentation should be required reading in order to obtain your Ruby or Python programming license:
http://norvig.com/design-patterns/
Think of all the countless lives that could be saved.
But they are more verbose and awkward to use in statically type languages, languages without first class functions (unlike Smalltalk, Ruby and Python), and methods like doesNotUnderstand, method_missing or __getattr__.
And languages with mixins/metaprogramming support can do pretty much all patterns in a much better way (this is easy to see on the paper[1] where Gregor Kiczales implements the patterns in AspectJ and see how much simpler they become when you have mixins).
The biggest problem with patterns is that people start with them, instead of refactoring to them when needed [2], which leads to a lot of over engineering (which is a form of premature optimization, and we all know what Knuth said about that).
Uncle Bob (creator of Selenium, author of Clean Code) talked about it recently: http://cleancoder.posterous.com/patterns-of-reality
I've tried reading through those slides, but I lose concentration after about the 3rd one because it's too disjointed.
They're often used ad absurdum in Java, to the extent where even in situations you don't need the complex functionality they support, you're stuck using them (often incorrectly because you don't need them) and they become a burden instead of useful.
Steve's example of the Strategy pattern is a good example of this. Contrast using this pattern in C (function pointers), in Java (inner anonymous classes conforming to an interface) and in Ruby (a block).
Any time you forget that, or start using phrases like 'Anti-Pattern', you lose (unless you're an expensive consultant, then you're about to get paid!). This appears to be the current forefront of Java development methodology (based purely on what I've read on HN).
This is ridiculous. Of course Dijkstra wrote code. He authored the first implementation of an ALGOL 60 compiler, if I'm not mistaken.
Though, technically for Dijkstra writing code was a bit beneath him, as he preferred deriving it using his Guarded Command Language. But the point stands. Dijkstra may have been a bit of a dick, but there's no need to libel a dead man.
[1] http://thinkexist.com/quotation/computer_science_is_no_more_...
His software, of which these are two examples, have low enough error rates that anybody who seriously evaluates today's software would do a double-take.