
A Quiet Defense of Patterns - SirOibaf
http://brooker.co.za/blog/2015/01/25/patterns.html
======
Retra
_" This school of thought then claims that the patterns at their scale and
above are not indeed patterns, because they have no use of patterns.

This thinking is flawed in two ways. The glaring flaw is in the restrictive
definition of patterns. The more subtle flaw is in not recognizing that they
have patterns of their own at similar scales to the ones that were rejected.
Abstraction is extremely powerful, but operating at higher levels of
abstraction doesn't appear to imply higher productivity or reduced needs for
patterns as a medium for sharing context."_

The reason we don't get a boost in productivity with higher abstraction is
because (a) we have to build such abstractions out of a great number of
smaller pieces, so that 'greater abstraction' means 'more work', and (b) it is
just very difficult to map our mental models into reusable abstractions. Not
very many people can do it well.

Yes, every language has 'patterns', but we call those linguistic structure,
syntax, or grammar. "Design patterns" refers to something else, (or if it
doesn't, it is just a confusing domain-specific renaming of the above.) The
problem with design patterns is that they are ostensibly _solved problems_ ,
and thus people shouldn't be implementing them except pedagogically.

Take arrays for instance. There is no "Array Design Pattern", and we don't ask
people to implement arrays every time they want to employ them. We ask them to
use existing array structure. Yes, you should understand how they work. You
probably should implement them once or twice and know how to recognize them.
But you do not say "Oh, just use the array pattern here. Start by rolling your
own array, since our language doesn't have array syntax."

We build arrays into the language so that they are easy to recognize and the
pattern becomes a primitive tool. If you have to keep rolling your own, you'll
never get past that. It will never become primitive, and you will stagnate.
That is what those who object to design patterns object to: by thinking of
them as elements of design -- the work of day-to-day programmers -- we won't
provide linguistic abstractions that allow them to become primitive tools.
We'll be stuck re-rolling our own arrays because people think that this is
what programming is all about. Tedium.

~~~
dragonwriter
> Yes, every language has 'patterns', but we call those linguistic structure,
> syntax, or grammar. "Design patterns" refers to something else, (or if it
> doesn't, it is just a confusing domain-specific renaming of the above.) The
> problem with design patterns is that they are ostensibly solved problems,
> and thus people shouldn't be implementing them except pedagogically.

Well, except that the whole reason for documentation of design pattern
implementations is that, in the languages for which they are documented, they
generally do not admit of a reusable library implementation because of
limitations in the abstractions available in the language. That's why people
(slightly inaccurately) say that certain languages (Lisps are frequently cited
here) don't need design patterns -- the kinds of things documented as design
patterns with implementation recipes for Java/C++-like languages can often be
implemented in library code in lisps (to a certain extent this is also true of
many dynamic OO languages, like Ruby, and sometimes in static functional
languages, like Haskell), so the kind of recipe-style presentation and fill-
in-the-blanks implementations seen in Java/C++ patterns just aren't applicable
in some other languages.

(Sure, you can address design patterns by building each one into the language
individually, the way you discuss with arrays, and that will shift _which_
patterns the language needs at the expense of a bigger base language. You get
more bang for the buck building languages which are expressive enough to allow
you to reusably implement a broad array of "patterns", so you instead of
implementation recipes you just need libraries with API documentation.)

~~~
Retra
I think part of this problem is that people want to invent compact, 'small'
languages, and leave the rest to libraries. This kind of thinking is what
makes it hard to move up, because it is just a variation on "our language is
ASM, if you want fancy stuff, just write it as a library in ASM."

Language design should be about saving the end programmer from having to do
extra work, not minimizing your core language and deferring the savings for
later. Of course, there is some push-and-pull here, because we want to make
languages small so that they are comprehensible. So what we want are the
smallest possible languages that can express a broad array of powerful
abstractions with minimal effort.

This is why I hate the "no language is the best" line of thought. (Which is
similar to "ever language uses design patterns.") There is no theoretical
reason why there can't be a best language. All we have is a history of
languages that suck to look at. You can't infer that all possible languages
suck at something from our short history of terribleness. It is 2015. What
kind of languages will people be using in 4015? How about 14015? Are they
going to be saying "It doesn't matter what language you use?"

------
programminggeek
Programmers by and large don't seem to understand the power of language
primarily as a communication tool and the lessons around communication we
ought to understand. We think in solitary terms as if it is of primary
importance how we write code individually instead of how we communicate with
each other (and the machine).

Patterns if done well give us a language to solve problems in sensible ways as
teams.

Instead, we worry about how patterns are named and argue over minutiae. We let
things like "exceptions should only be used for exceptional behavior" distract
us from effectively communicating with each other.

Our industry sees things like FP, OOP, Design Patterns, etc. as an exercise in
taxonomy when building software is an exercise in communication. It's like we
are writing a novel, but we are more worried about the names and families of
characters than the actual plot itself. That doesn't make for a good book and
it doesn't make for good software.

------
Jare
In my experience, design patterns encourage two big problems:

\- Deciding on a solution before having explored the problem. "I have a
pattern for that."

\- They act as shared context only on the surface; all the details and
subtleties of the pattern as an implemented artifact are rarely shared, and
communication suffers.

In practice, they tend to make the easy stuff easier, but the hard stuff
harder.

~~~
jacquesm
That goes for any mis-applied tool. If you approach the world with your
toolbox ready in hand and you refuse to adapt your tools to the problem then
you get this mismatch. Tools were created to solve repetitive problems, if
your problem is not one of those then you should improve your toolset, maybe
come up with an entirely new tool or maybe you should adapt an existing one
until it works better for your application.

~~~
Jare
I agree, my point is that in practice, patterns encourage that kind of mis-
application in many many programmers, and not just the bad ones. The reasons
why they do are part of years-old and still unsolved debates.

But I know what I saw: fresh off my love affair with the Lakos C++ book, I
though GOF was the next cornerstone of OOP and a must read for everyone. Over
the next few years, design debates and proposals where design patterns
featured more and more prominently, started turning into bizarre minutiae and
half-explored problem discussions. Again, simple and noncritical pieces of
software seemed easier to describe and even develop, but the hard stuff became
harder to manipulate, overabstracted, took longer to be truly finished
(although it got to MVP state faster), and usually much less performant.

------
zamalek
To me patterns have always been incredibly useful as a book of problems that
have been solved, somewhat like a chess playbook. Would I ever implement them
directly? Maybe, if they were directly appropriate. Often I find that my
solutions are pattern inspired, "factory-like," "observer-like," "strategy-
like" etc. Even more frequently my solutions are a hybrid of multiple
patterns.

That's where I see their value: they are extremely good blueprints. Like every
tool, they are incredibly powerful if used correctly. They are most often
misused, especially in the case of verbatim use.

------
cessor
The author suggests a common opinion on patterns, that I have seen violated a
billion times:

> Two people with a common set of patterns find it easier to communicate [...]
> than those without one.

> [...] writing down our shared context lowers the barrier to entry.

In my experience this is often not the case. Patterns come along with labels
and the labels will be put everywhere in a codebase. Assumptions get made and
replace discussions, leading to a diluted codebase. For example Repositories
will become synonyms for "thing that does database access", and will then be
reduced to stupid GetByID wrappers [1]. Even worse, some patterns make entry
really hard.

I used to work with C# and ASP.NET MVC. There, a view is the thing that
contains markup, the thing controlling the input is the controller. Then I
started using Flask and was utterly confused, since there the functions with
the @app.route decorators, which are run on the server and then return markup
rendered via jinja2 templates, are called view functions. In Django this is
understanding is the same.

I was really baffeled. I could not reapply my understanding of the patterns
across these domains. This is just one explicit example that I wrote about in
my blog [2], but I really made the general experience that patterns replace or
inhibit discussions, rather than improving communication and understanding.

[1] [http://philcalcado.com/2010/12/23/how-to-write-a-
repository/](http://philcalcado.com/2010/12/23/how-to-write-a-repository/)

[2] [http://www.cessor.de/on-patterns](http://www.cessor.de/on-patterns)

------
emsy
Would patterns exist if we had no name for them? In my opionion, definitely
yes. So giving them a name doesn't change the nature of patterns. Problems
arise when a, now named, pattern gets misused. The misuse is therefore
_always_ commited by the developer. The two main critic points I've read in
the comments were:

\- Developers try to find a problem to use a pattern they know

This error is mostly commited by people who learn the first time of patterns
and are giddy to use them. I wonder if this was less likely to happen, had the
GOF included a warning about this in their book.

\- Developers keep using the wrong terminology and this causes patterns to
become squishy

Just stick to the GOF terminology and your good to go.

In my eyes, the patterns discussion is just an indicator for a greater
"problem": Anyone can become a software developer. I won't elaborate on the
positive aspects of this. But it's clear that areas with a higher entrance
bar, like law or health, have a greater professionalism and, among other
advantages, a standardized terminology.

------
ArneBab
> The critics may be right that it devalues the craft, but we would all do
> well to remember that the craft of software is a means, not an end.

I don’t think that patterns devalue the craft.

Also they helped me get a better understanding of what I do. For example in
Python you can create a Singleton by simply accessing an instance which is
instantiated directly in its module. The pattern is built-in and very easy to
use, but I only started making heavy use of it when I learnt the Singleton
pattern. It was then that I realized how much value this simple language
feature provides.

> “In a functional language…you end up programming in concepts that eliminate
> design patterns all together.”

I saw lots of ad-hoc patterns which have to be understood to understand the
code.

------
praptak
I was a bit confused whether the author argues for patterns as Platonic idea,
patterns as popularized by GoF or patterns as popularized by Christopher
Alexander.

The most vicious arguments I have read were about GoF not keeping the spirit
of CA. One example is GoF being a sort of disconnected catalogue, while CAs
patterns are supposed to generate the world. I don't see these referenced in
this article.

------
hawleyal
I disagree. Patterns are often just used as a way to work around the
limitations of expression in a given langauge. Sure, they can be useful. But
in the long run, they are not the goal, they are the unfortunate means to an
end.

