

Let's Do Some Engineering Pt. 1: Design Patterns - sha90
http://gnuu.org/2010/03/26/lets-do-some-engineering-pt-1-design-patterns/

======
tptacek
Painful and a little embarrassing. The GoF patterns exist primarily to make up
for the fact that you're _not_ in Ruby. The timeless response to any article
referencing them:

<http://norvig.com/design-patterns/>

Sort of funny that he mentioned dependency injection as a benefit of one of
these approaches; building things around DI was one of the reasons net-ssh got
rewritten. When you find yourself writing Java in Ruby or Python, stop, take a
step back, and reconsider.

~~~
sha90
"GoF patterns exist primarily to make up for the fact that you're not in
Ruby"- this is the epitome of ignorance and the exact denial referred to in
the article. I must have missed that part in Design Patterns that said "if you
use Ruby you should not use this book".

But hey, I guess the Ruby stdlib includes the "Singleton" pattern for fun
right? Not because you'd use it, or anything. Same with delegates. And I guess
Rails didn't actually implement Martin Fowler's Active Record, Action
Controller and MVC patterns? You just dreamed those.

Wake up. Your comment is painful and a little embarrassing. Design patterns
are language independent. They are not implementation, they are descriptions.
They can be used in any language, and they are used in Ruby.

~~~
tptacek
There is a world of difference between what Schmidt tried (and failed) to do
with Pattern Oriented Software Architecure and what Java programmers managed
to do with the Gang of Four patterns.

You really, _really_ ought to follow that Norvig link I posted. There is more
insight and utility in that 10 minute read than in everything Fowler wrote.

There is a "Singleton" in the Ruby standard library, but since every Ruby
class inherently includes a "singleton", you'd be embarassing yourself to use
it. Note that it occurs nowhere in current Rails. Note also that "Singleton"
is notoriously derided as an example of how superficial some of the GoF
patterns are; it is, at its core, a puffed-up way of saying "global variable".
Maybe a better name for it would be "very global variable".

Regardless, the twin problems with this blog post remain:

* The idea behind design patterns _isn't_ that they give you a library of pre-built components that you can pick up off the shelf and use to assemble complete programs. But that's exactly how this blog post uses them.

* The GoF design patterns in particular describe ways to patch around the weaknesses of C++ and Java; they are, as Norvig writes, transparently implemented in modern languages, and reimplementing them is something akin to writing your own string matching or filename globbing code.

~~~
sha90
"Maybe a better name for it would be "very global variable"."

The better name for it already exists: it is the __Singleton pattern __,
because OOP software developers already understand this concept. You don't
need to invent new names, this is why patterns exist. Also note that whether
or not you use the "Singleton" mixin in Ruby, you are still using the
_Singleton pattern_ whenever you define a class with no constructor. Yes, you
can do this without "include Singleton"; no, this does not mean you're
magically using some new concept nobody's thought of before. You're still
using Singletons.

* The blog post doesn't _use_ any patterns at all. Given that there are no code examples or suggestions, I don't see how you came to this conclusion. The blog post never tells you how to use patterns, it tells you _why_ you use patterns. Where does it advise you to "pick up components and use them to assemble complete programs"?

* Java did not exist when GoF wrote Design Patterns, so it clearly was not addressing any weaknesses of that language. Your point is DOA and you seem to be pulling this out of your ass. But, to elaborate: GoF isn't describing ways to patch any languages, it's describing ways to attack software problems. The idea of using a Strategy pattern (for instance) is universal among any programming language, it has _absolutely nothing_ to do with code. So is using a factory method. Ever used `ActiveRecord.build` or 'create_with_...'? That's a factory method. The same concept applies with adapters, facades, et al. How you implement the pattern is completely irrelevant to the entire book. You could do it with dynamic dispatch or classes, the book doesn't define the patterns by their implementations. The point is you're using them. Pretending you're not is some kind of childish posturing so you can tell yourself you're "not doing anymore Java". I'm sorry you experienced your Java nightmares, but design patterns have nothing to do with that language.

~~~
tptacek
How do you even write an paragraph about "whether or not" you'd use the
"Singleton" mixin in Ruby? That's the point of this argument. You _don't_ use
it. Ever. There is absolutely no reason to use "Singleton" mixins in a
language that already represents "classes" as objects.

Similarly, you don't write "Strategy" code in a language that has first-class
functions, and you don't write "Factory" code in a language that in which
classes are first-class objects like everything else. You don't need a
"Command" pattern in a language with closures and lambdas. And you don't need
an "Adapter", "Facade", "Bridge" or "Proxy" in a language where function calls
are already messages.

You would have to _deliberately_ write a book with _no truth in it whatsoever_
to come up with a list of "patterns" that have no applicability at all. The
Gang of Four didn't do that. It's an interesting book with valid ideas. But
the approach of constructing programs out of "patterns" has been discredited,
_particularly_ and _on account of_ the case where people use the Gang of
Four's patterns as their template.

Incidentally, you think I'm blazing new trails of ignorance here, but I am
very late to the party with these comments, which I've mostly shoplifted from
much smarter developers.

Here's one such comment, from a (probably) better developer and (definitely)
better writer than me. Tell me what you think of it:

 _This practice is not only common, but institutionalized. For example, in the
OO world you hear a good deal about "patterns". I wonder if these patterns are
not sometimes evidence of case (c), the human compiler, at work. When I see
patterns in my programs, I consider it a sign of trouble. The shape of a
program should reflect only the problem it needs to solve. Any other
regularity in the code is a sign, to me at least, that I'm using abstractions
that aren't powerful enough-- often that I'm generating by hand the expansions
of some macro that I need to write._

~~~
sha90
You don't "write a paragraph", you use a word. In fact, the point of patterns
is to _save_ you from writing a paragraph. Again, not to repeat the entire
blog or anything, but that's why the words exist.

    
    
        # This is a singleton class
        class MyClass
          class << self
            private :new
            def instance; @instance ||= new end
          end
        end
    

Without looking at the methods or even the implementation I now know not to
try to call `MyClass.new` because it's defined as a Singleton class. Simple.
No paragraph necessary. You _would_ need a paragraph if you didn't write this
simple word.

And guess what? _I just used the Singleton pattern_.

~~~
tptacek
Same fallacious argument: that when you do something that can be described by
a design pattern, you're doing pattern-oriented software design.

Same straw man argument: that anybody who points out that the GoF patterns are
'considered harmful' is arguing against concise, regular descriptions of
design constructs.

What's your point? The GoF patterns already lead you astray; just a few
moments ago, upthread, you had to waste cycles considering whether to use a
_library_ to implement a "singleton pattern". The endpoint of this thinking is
the SOAP4R code.

Design patterns are code smells.

I have good news for you. You're working in a modern language. You don't need
to think about patterns. You don't need to spend even 15 seconds up front
thinking about how you might decompose your problem into "Proxies" and
"Factories". You can get to work right now on your problem domain.

Because you're in a modern language, when, down the road, you discover that
you need, say, to move a component into its own address space to collect calls
and cache them, Ruby already gives you a "Proxy" construct. It's
"method_missing" and it's idiomatic to the language. You will not need to
dramatically alter your architecture to remote the method calls to a cache
process; you'll just change the name of the class you call, from
ExpensiveCollection to CachedExpensiveCollection, which will be about 15 lines
of code long.

And so there's another problem with using the names that OOPSLA dorks came up
with 15 years ago. You're fighting the language's own idioms. Ruby doesn't
want you to think in terms of "singletons" and "factories" and "commands". It
wants you to know how closures work, and how messages are different from
simple function calls.

Another good article to read is that post by Wil Shipley about not writing too
much code up front. Someone else can find the URL for you.

------
jamesgolick
What's painful and embarrassing is when somebody who didn't actually _read_
the article calls it "painful and embarrassing".

> Patterns are still patterns whether you acknowledge them or not, and they
> are not defined by the LOC or number of classes they require in language X.

> Refusing to admit that patterns are used hurts your development team and the
> community, because patterns (simply identifying them) serve a very important
> purpose.

> Well, design patterns are just like [agile] metaphors, but they are meant
> for code, not UI.

> For instance, consider the factory pattern versus the builder pattern. Both
> are concerned with creating objects, but a builder is also concerned with
> the assembling of the object. This is a relatively subtle but pretty
> noticeable difference. Telling someone you are using a "builder pattern"
> should immediately ring a bell in their heads saying, "oh, it’s not just a
> factory".

Patterns are specific nomenclature not implementation.

