4 ms·
Ask HN: GoF Design Patterns and Dynamic Languages
Hello -
Excuse me if this question is elementary, but it is something that I would like to get a better understanding about in order to be able to code more properly/etc.
If I understand correctly, the GoF Design Patterns were originally created to address some limitations with the object oriented approach used by Java at the time (Please correct me if I am mistaken).
Is it true that dynamic languages address this limitation to some extent and thereby reduce or eliminate the need for the use of some of these patterns?
Specifically, my questions are:
* In a language like Ruby for example, do you find yourself using GoF patterns or does the fact that the language has functional aspects/duck-typing/etc. reduce/eliminate the need to use these patterns?
* If the above is true, are there new patterns that you find yourself using?
* If one is starting with dynamic languages today, is learning/mastering these GoF patterns still a requirement?
My intention of course is not at all to create an argument about this topic, but rather to learn how to best approach learning programming now in 2012, specifically with dynamic languages in mind (Such as Ruby and CoffeeScript, for example).
Furthermore, I am not a CS student and have been teaching myself programming over the years (Started out with scripting for system admin purposes but gradually became interested in programming/development itself). Being self-taught has its virtues and limitations. One such limitation perhaps is the fact that I may have missed out on some of the important teachings such as these GoF patterns in a classroom setting/etc.
Thank you for your time.
- gruseom 14y agoI'll take a shot at answering, but you should know that people disagree about this. The GoF patterns predate Java. They came out of a "software patterns" movement, inspired by Christopher Alexander's beautiful A Pattern Language about how to make great buildings, to capture various problems that come up frequently in software design and formulate standard solutions to them. The hope was that this would lead to a body of engineering knowledge that people could learn software design from, instead of everyone having to figure this stuff out on their own or (at best) from oral tradition. Also, the idea was to provide a standard vocabulary for common constructs, so for example instead of me saying "wrap" and you saying "delegate to" we would both say "decorate". But it didn't work. Software patterns turned out to be at just the wrong level of abstraction: too generic to be applied directly to real problems and too specific to be good as principles. They confuse inexperienced programmers who are told that good code makes use of patterns and so try to find ways to organize their programs around them. That is disastrous: you get a bunch of abstractions in your code that are not there because of the problem you're trying to solve, but because of preconceived ideas about what good code looks like. What's particularly bad is that the patterns are seductive: they seem to make sense when you read them, but as soon as you get to your concrete problem, it's hard to see how to apply them. If you're inexperienced, you blame yourself and think you're doing it wrong, when what you ought to do is reject the abstraction as not fitting. People who like software patterns will say that of course you're supposed to apply the patterns appropriately, not mechanically. But this leaves you trapped in a circle. If learning the patterns themselves doesn't teach you how to make good code with them, what's the point of learning them, and how do you get good at software design? People who dislike software patterns add that in many cases, the patterns amount to mere code repetition, caused by the fact that a given programming language isn't powerful enough to get rid of the repetition, and that the solution is not (in PG's memorable phrase) to be a human compiler but rather to just use a more powerful language. In my opinion, you'd be much better off just writing real programs to solve interesting problems. No one has a good general theory of programming. What you want is practice. Learning patterns will fill your head with a lot of abstract gobbledygook without telling you which bits are useful in specific cases. Don't start with a solution or a set of solutions in mind; always start from and return to the problem itself. It will tell you what to do, or at least what to try. Your job is to try those things and see which ones fit - they are the ones that solve part of the problem without adding extrinsic complexity. Learn your language well. Learn more than one language. Read other people's code, especially by anyone you think is particularly good. Finally, when you write a program, think hard about whether you could do it more simply: that, over time, is the royal road to good software design. And if you want to get stronger in CS, avoid software patterns and software process and most of what's called software engineering, and just learn more about the classics, like algorithms, data structures, operating systems, compilers.
- tptacek 14y agoThis is all true, but if you haven't read Schmidt's patterns of distributed/concurrent systems, and you keep an open mind, you might find the approach has more value; "Abstract Factory" did more harm than good, but "Half Sync/Half Async" is pretty good stuff.
- gruseom 14y agoThat may well be true. My concerns are primarily pedagogical. I took a quick look at the work you mentioned and most of it seems to be considerably higher-level than the GoF patterns. Somewhat counterintuitively, that makes it less abstract. (Example chosen at random: http://www.cs.wustl.edu/~schmidt/PDF/lf.pdf http://www.cs.wustl.edu/~schmidt/PDF/lf.pdf) That's a good thing. It means there's more meat on the bones. The kind of patterns I'm critiquing are the one-level-up-from-language-constructs kind, which (I guess we agree) are different. There seem to be some good papers in that collection. I might even forgive them the UML!
- tptacek 14y agoThis is a good question, but the specific answer to it is unfortunately very short: if you're writing Ruby, using GoF patterns is non-idiomatic. In parts this is because, as Norvig points out†, many GoF patterns are obviated by basic features of the language, like first-class class variables. In parts this is because those features and others change the way you design programs in Ruby. It's less common to build complex pipelines of carefully layered objects in Ruby than it is to implement (for instance) DSL's. And finally, in parts its because the "GoF patterns" are themselves a misconception about pattern-oriented programming. Often when we talk about "idioms" in a particular language, we're often just talking about patterns- by- another- name. When the Github guys write Unicorn to do concurrency and process management "the Unix way", they're dealing in patterns that Schmidt and the OOPSLA/distributed systems people hammered out 10-15 years ago. There's a lot of work that's fallen out of fashion that we're inevitably going to rediscover. † http://norvig.com/design-patterns/ http://norvig.com/design-patterns/