I learned a lot from reading the GOF book two or three years into my programming career. I think like most people, I'd already invented a few of its patterns, like pluggable Strategies, but it was great to have shared names for things.
On the other hand, I interviewed a while back and was talking about a web sockets project where my Javascript received a callback when a message arrived. "Did you think of that in terms of Design Patterns?" they asked. "Not really, callbacks are pretty common in Javascript." They really didn't like that answer. If I could think faster on my feet, I'd have whipped out that quote from Peter Norvig: "Design patterns are bug reports against your programming language."
This person sounds super jaded. Like they didn't get a job because they didn't know about some pattern they were asked about.
The thing about the GOF book is that it gives you a great foundation for designing great software. No, they aren't the only patterns out there, but you are going to find at least some of them in any well designed system. You will also see a lot of code that is clearly based on a GOF pattern, but evolved from that to solve a specific problem.
For instance, you can't get a web job these days without being familiar with MVC. And really, you should know what component modern day web frameworks are missing (an observer). You will probably use some rendition of the chain of command at some point in your career. Then you have the proxy pattern, bridge pattern, adapter pattern which are all popular as well.
So sure, hate on GOF. But you're completely missing something if you do, and expressing such distaste for it makes you look bad (imo). GOF doesn't take away the creative aspect of programming, it actually facilitates it by giving you a solid foundation of which to work. So while some will perform a piece of sheet music, others will use the sheet music as inspiration to create something new and beautiful.
What I got from the article is that these patterns are guidelines, not paths carved out of stone that you have to follow. How he presents it is irrelevant to what he's trying to convey.
> Yet people insist on you naming a design pattern in interviews, like it's a secret handshake, or asking a carpenter if they know any kinds of wood. What does it prove? Nothing.
Looking at someone's code is more useful than asking if they know patterns. But some knowledge of patterns is a good thing IMHO.
For example, if I can point at some of my code and say "Yeah, that's kind of like a factory" and know I'm understood by my teammate, then that's a good thing.
One goal of the design patterns movement was to introduce a terminology that could be shared and understood. I think they succeeded to some degree, because employers are looking for familiarity with this terminology. Why is it such a PITA?
> Programming isn't paint by number, every day you make decisions on what to write and how to design or structure the code in a continuous basis.
But wouldn't it be quite cool if you could check your thinking against other peoples successes and failures? Patterns simply catalogue problem/solution, I don't think you're supposed to implement them in a paint by numbers fashion.
You are right in such a deep sense that I wish I had more than one upvote to give.
This is what people mean when they say a design pattern represents a deficiency in a language: the very fact that it's a design pattern and not, say, a library function is precisely because that language provides no way to abstract it away. Hence, rather than being something that we can turn into a reusable code artifact, the pattern instead becomes a piece of programmer lore, existing only in comments, in design documents or in people's heads.
You're thinking wrong. You're thinking like you're going to only use one language ever in your career. You're not (unless you have a very stunted career).
Learn what you're doing, independent of language. Then also learn what you're doing within the language.
I strongly disagree that I am "thinking wrong". I think you're saying that design patterns are a useful abstract way of thinking about your problem that you then translate into code using whatever tools are available in the language you're using. I think there are some patterns for which this is true, but the majority don't fall into that category.
This explains thoroughly what is wrong with design patterns ala GOF. It's not that particular frequent patterns in particular languages or enumerating them in academic fashion is wrong. It becomes wrong when sophistry of these band-aids to language flaws are raised as somehow being really important, when actually they are just reactions to accidental complexity. It often creates unnecessary complexity to description of systems and cargocult overengineering.
I would claim that it's much more beneficial for budging engineers to program something they have not programmed before (like a space invaders clone or a scheme interpreter) than to remember each GOF pattern.
And, since these band-aids are unnecessary in several languages, it would be much more fruitful to learn one of these languages rather than memorize some band-aid.
The reason the patterns are common is that they are pretty much obvious after you understand the low-level language and you are familiar with some higher level language.
It's nice to be able to give things names, but, being able to name a bird does not mean you know anything about it's important characteristics. Or, to misquote Feynman, "GOF design patterns are pretty much as important to software engineering as ornithology is to birds".
Also, if you read Christopher Alexander's work, I would claim that GOF patterns are not patterns in the sense Alexander uses.
I've seen quite a bit of damage done by GOF patterns. Simple code bases become more complex due to an implementation of some GOF pattern because that's "the modern way to do it by the book".
I would claim that it's important to first figure out a most simple way to do something, and if it fits into some GOF category then fine, you can identify it and move on.
I wouldn't say "what is wrong". I mean, the patterns stand on their own merit: they provide a recipes for solving commonly recurring program design problems in Java, C++ and their ilk. "What is wrong" is making a religion out of them: elevating these patterns to an overly important status, as if they are some important generalities in software engineering, if not in fact computer science or even mathematics.
While that paper is specifically addressed to "Dynamic Languages", I suspect you'd find similar things with modern static functional languages with more robust type systems (Haskell, particularly.)
I actually found that comparison to be a great example of why design patterns are useful. By naming the pattern, Norvig was able to instantly list 16 ways in which dynamic languages solve real-world problems.
I had just finished undergrad computer engineering when the GoF book was published and it was a total revelation at the time. But as the author says, good ideas can be made terrible by too much slavish devotion and not enough thinking.
I think the key usefulness of books like "Design Patterns" is to create a common language. Now, when I say "this is an observer" people instantly know it subscribes to an "observable" which notifies its observers by calling their callbacks.
Now... What I am sick of is people misapplying those patterns in situations and languages they really shouldn't.
is quite a mouthful. But if everyone's familiar with design patterns, then you can just say "Oh, it's a Builder pattern" and everybody knows what you're talking about. Same goes for many, many other situations; familiarity with MVC will go a long way towards understanding angular.js, and familiarity with Chain of Responsibility will teach you about WSGI or Django Middleware, or the State pattern will help you understand trampolines in interpreter implementation.
The adage "those who don't know history are doomed to repeat it" comes to mind when I read this article.
If you simply write off the GoF patterns then you're likely to spend a lot of time creating inferior solutions to common problems. You are less likely to recognize a common problem when you see one. At the same time, people who just see the GoF patterns as some sort of bible will implement things in a ridiculously complicated way because they're trying to use as many patterns as possible.
Basically they're just tools to have in your tool chest. You have to learn how and when to use them.
> Yet people insist on you naming a design pattern in interviews, like it's a secret handshake, or asking a carpenter if they know any kinds of wood. What does it prove?
It proves you can communicate succinctly with other developers. I can't count the number of times I've had a coworker laboriously explain some design they "invented" only to reach the end and realize they just described an observer, or command, etc.
Sure, I get sad when people overuse design patterns too, but I find them incredibly helpful as a communication tool.
that's as good as saying "i'm sick of arcs, square windows, rafter roofs and linked lists". of course patterns aren't the end-all-be-all of software development. but it's the trait of a good craftsman and engineer to know what patterns exist and how to use them.
Sadly, and in that I agree with the author, people in interviews only ask for knowledge of patterns, not when and when not to use them.
in that sense, the title better were: "I'm sick of people thinking of patterns in an idiotic fashion", avoiding creativity at all cost". But then, that's just complaining about the single-mindedness of less experienced colleagues.
The patterns themselves and knowing how to use them I still consider a valuable asset and in parts, the author says that.
But beyond that, the value of patterns is that you can easily communicate with other developers about architectural decisions. And communication is 80% of software development in a team.
> that's as good as saying "i'm sick of arcs, square windows, rafter roofs and linked lists".
Well, no -- except for the last, which we'll come back to -- because software isn't the same thing as physical architecture. The nature of software is that components can be and should be reusable, so if you have to rebuild the same thing from a complex "pattern" (more than a simple parameterized constructor or the equivalent) each time you use it, it means that the tool (programming language) you are using has a failure of reusability. With physical architecture, you obviously need to build a new copy every time you need one -- windows are fundamentally not reusable.
Now, for linked lists, yeah, it would be silly to be sick of linked lists as a concept when building software.
OTOH, you can legitimately be sick of having to build a struct with a data member and a next pointer and all the associated manipulation functions every time you need a linked list of <new data type> -- that is, sick of linked lists as a GOF-style Design Pattern -- rather than being able to (if you want to be exceptionally explicit about naming a type for the list) doing something like:
type newDataTypeList = [NewDataType]
The better your language is, the less you have books of "Design Patterns" with implementation recipes, and the more you have code libraries where the documentation of the "pattern" covers effective use, rather than implementation.
> software isn't the same thing as physical architecture.
and software isn't the same thing as a design pattern (neither are components). The pattern describes the /concept/ and allows the builders to call an arc "an arc" instead of describing the tedious 100 steps required to actually build one and the explanation of why it works.
Reusability isn't a relevant aspect of design patterns - this is a hallmark of implementation. I can implement 200 singletons and have no need to re-use them. Same goes for windows - just because I have built a bathroom window doesn't mean I need (or even want) to reuse it for my living room.
And language 'quality' is not even a metric, I don't see the relevance of your last paragraph.
> and software isn't the same thing as a design pattern
And GOF-style design patterns -- which are heavily implementation-recipe-centered -- aren't the same thing as design patterns more generally.
> The pattern describes the /concept/ and allows the builders to call an arc "an arc" instead of describing the tedious 100 steps required to actually build one and the explanation of why it works.
GOF-style design patterns actually describe the tedious 100 steps required to actually build them, and are in particular selected not by their general applicability but by the fact that they are specifically things that cannot be abstracted in the languages of the time that the book drew from, e.g., they are largely implementation recipes for things for which implementation recipes rather than reusable libraries are required in the common OO languages of the time the book was assembled.
> I can implement 200 singletons and have no need to re-use them.
Yes, but the reusability I'm talking about isn't the individual implementation but the common infrastructure -- with a language that is more flexible than, you can build the infrastructure for a singleton once, and the next time you don't have to build a whole singleton implementation, just the bits that are unique. With physical architecture, you have to build the whole thing each time, so implementation recipes are, to an extent, an unavoidable accompaniment to design patterns, rather than a sign of a problem with the implementation medium (in the case of programming, the particular language.)
I don't know that you understand the true value in patterns. Take for instance this series of numbers. 1,1,2,3,5,8... I bet you can look at it and say hey I recognize that pattern, 13 will come next because its the fibonacci sequence. Immediately, you can look at 5 and 8 add them together and know what comes next. You don't have to confirm the math that lead up to 5 or 8. You know because you understand the patter.
Patterns in software mean the same thing. If I can recognize the pattern through reading code, UML, or by being told with jargon, I am going to save time and energy.
I am going to assume you are not a musician or music theorist or something along those lines. Mainly because music is patterns.
MENSA describes intelligence as the ability to recognize patterns. (Couldn't find my source on this.)
But lastly, GOF didn't tell people that their patterns are a means to an end, they are a starting place.
I'm tired of design patterns, too. One of my favorite quotations these days is Brendan Eich's paraphrasing of a sentiment attributed to Peter Norvig: “Design patterns are bug reports against your programming language”.
That said, if you can write a rant of this length on the topic without once mentioning how they facilitate higher-bandwidth communication between team members, you're missing something.
Asking about design patterns in an interview is not a secret handshake. Instead, you are being tested to see whether you're just bringing your own programming talents in isolation, or whether you're also bringing along the force-multiplier of communication.
In my interview revenge fantasy I imagine turning the tables on the interviewer:
"Before I tell you what I know about design patterns, let me ask you a question. From speaking with you, I can tell that you are articulate and have a good command of the English language, in other words, you're a good communicator.
Now, if I asked you to give me a sentence containing a gerund in a preposition phrase could you? Probably not, even though you probably don't go a day without writing such a sentence. Could I assume that because you aren't familiar with the terms in the above question that you probably aren't a good communicator?"
I somewhat agrees with the author. But I think GOF Design Patterns is only ONE step in the right direction and it is time to move beyond that.
It is because of the GOF Design Patterns that we started to talk about anti-patterns. In my opinion, learning about the anti-patterns maybe more important than learning about patterns.
The author's analogy with Mozart's music is curious. Mozart's compositions are closer to the classical forms of a symphony, concerto, etc. than other well known composers who came later. He didn't slavishly follow some rules, but other composers broke way more rules than he did.
I think what you're trying to say is that you're sick of people misusing or otherwise applying GOF patterns without thinking about them. Being 'sick of GOF patterns' is something entirely different.
Not entirely different. If a thing is so consistently misused as to controvert its original purpose, it's fair to say you're "sick of X" as a proxy for its community or educational standards or other meta-application.
I don't agree with the author's approach either, but I don't think he's trying to say what you think.
I've always taken these "design patterns" to be a Shibboleth of the bottom 80-ish percent of programmers.
The mediocrities can't handle math. If they dig deep enough into any technical area, they get confused and insecure and pissed-off. Design patterns is the Revenge of the Not-Nerds. It's to use the language of the business to turn the tables and make the actually competent feel queasy and unsure of themselves in the (artificially stupid yet complex) environment. It ends up reinstating a mediocrity-protecting connections- or seniority-powered system because no individual can get anything done.
I call the programmers who like that nonsense "math haters". (Rhymes with "death eaters".) Instead of y = sin a*x, which is "too mathematical", it's a Vibrator object with an .apply(double x) method that returns a double. That class of functions (parameterized by a) is a VibratorFactory. But since there can only be one, why not seem extra business savvy and call it a VibratorFactorySingleton. I'm going to throw in Proxy and Abstract and Visitor in there too, not because I know what they mean in this context (I don't) but because no one else does either so I can get away with it. It's an AbstractVibratorFactoryProxyVisitorSingletonFactory.
All because I needed to use a simple trig function. But (to the math haters) trig functions are scary!
So much of this "enterprise-y" nonsense is there not just to dumb down, but to smart-out (as in, drive the smart people out of) programming. It serves the interests of characters like Twitter's PHP CEO (obviously fictional, but people like him exist) who seek to commoditize programming at all costs.
What an obscure load of tosh. I might as well say that all the maths-nerds don't really know how to program because they don't understand design patterns properly, as evidenced by them hating on it all the time.
But of course, I wouldn't say that because I have absolutely no evidence and it would be based purely on my close-mindedness and preconceptions. (I also wouldn't say it because I have no hatred towards "maths-nerds" !)
And also - when has a pattern ever been used to abstract away a maths problem? I certainly haven't seen it!
Understanding patterns, but more importantly, design principles, help when writing code because of the limitations of the language (any language) in properly describing the problem domain. If those principles lead to the creation of patterns which are then given names and taught to the masses, I cannot understand how learning about them would make someone a worse programmer.
I agree with you in general. But learning the design patterns superficially, and applying them where they don't really fit, can in fact make someone a worse programmer. Hopefully they'll grow out of it, so the "damage" is part of the student phase, but some probably do get stuck there and never progress.
For me, design patterns are a good thing. If it's a phase, I'd prefer people to be stuck there rather than never learn them.
My reasoning is that using a pattern is like documentation. If I see a pattern in some code, i barely have to read the code. Code is hard enough to read as it is, patterns make it easier.
I've heard various figures over the years but one that i think is a decent estimate is that maintenance is 80% of the SDLC. That means reading a crapload of code. Any time you can reduce the burden is a good thing.
It's true that a lot of GoF's design patterns are particular to languages like java and c#, and not relevant to dynamic languages especially.
I think your idea about applying design patterns where they don't fit isn't really the source of the problem. Some developers aren't good at understanding the problem they are faced with, so they do the wrong thing. That isn't anything to do with applying or not applying design patterns - it's a different discussion altogether.
That's well and good, but quite a lot of business value can be created using sub-elite programmers.
The problem with not having a good common vocabulary is that it makes it harder and harder to ever have proper engineering in software.
That said, your example of not being able to use trig is flat out unacceptable--that's things taken much, much too far. Even an average programmer shouldn't be afraid of basic trig.
Completely agree. If you're building a forecasting module for an ERP system, you're probably not going to be able to hire CS grads out of MIT or Stanford to staff on it. You're likely going to get some dudes from India with little experience outside the other Dilbert-esque ERP systems they've worked on. But these guys can still be productive if given the right structured environment, and that's what coding patterns give you.
Furthermore, "rockstar" developers are often a hinderance on these kinds of projects: they take workarounds that are technically sound, but harder to maintain. Use of consistent design patterns makes maintenance a hell of a lot easier (especially when using less-talented developers). Rockstar developers are great in a startup when you need your developer to be a systems architect as well, but they're less useful in rigid functional projects like big enterprise software projects where developer and architect roles are rigidly separated.
But the example OP listed still makes sense: wrapping the example trig in a function makes sense if you plan to modify that function later and it's used in several places across the project.
The "enterprise-y" garbage you note has almost nothing to do with the mathematical competence of programmers who implement it.
You write as though programming is an exercise in mathematics. It's not, in general. There are specific problems where mathematics is actually a component of the problem/solution space, e.g. mathematical research, scientific computing, in which programming is the form of the solution to the math problem (analogous to, e.g. "express your answer using set notation", except in this case it's "express your answer in the form of a computer program"). Mathematics may underpin some of programming, and most often in some areas of computer science, but the vast majority of software development has very little to do with math.
Why bring a thought-up ridiculous example when you can post a link to the infamous AbstractSingletonProxyFactoryBean?
Anyway, patterns aren't some "evil plot" by "math haters", they are simply recipes that solve recurring problems. They weren't really "invented" by GoF or anyone else, these things tend to emerge when a lot of people people do a lot of software engineering projects.
Also, you're wrong if you seriously think that the majority of software engineers needs to know trigonometry (or any kind of math at all) to do their jobs.
The only thing worse than "enterprise-y" nonsense is blogs of lame psychoanalysis of characters from a fictional office sitcom complimented with its own language-stan to throw off outsiders, all in the service of some Nazi-like narcissitic crusade of "smart" vs "idiot".
But see, even math can be misused in the same way. Instead of y = sin a * x, it becomes both a functor and a monad. See, that's even more mathematical!
Those who have only a superficial understanding can (and will) mis-apply anything. That includes all of us, at some time in our careers. Those you dismiss as the "bottom 80" include anyone starting to learn anything. Some of them will grow to know how to use the tools well; some may never do so. But don't condemn the entire tool because you've seen it used badly.
More: You seem to be condemning everyone who doesn't program your way as being stupider than you. That is far more likely to be arrogance than to be the truth.
On the other hand, I interviewed a while back and was talking about a web sockets project where my Javascript received a callback when a message arrived. "Did you think of that in terms of Design Patterns?" they asked. "Not really, callbacks are pretty common in Javascript." They really didn't like that answer. If I could think faster on my feet, I'd have whipped out that quote from Peter Norvig: "Design patterns are bug reports against your programming language."