4 ms·
Is this article a joke? "" Patterns. Can’t live with ’em, can’t live without ’em. Every single design pattern makes your design more complicated.
by Sumaso 12y ago
Is this article a joke?
""
Patterns. Can’t live with ’em, can’t live without ’em.
Every single design pattern makes your design more complicated.
Visitors. I rest my case.
""
A design pattern demonstrates a solution to a common programming problem! How can you take issue with them? You don't need to program in an OO language to use the concepts that design patterns describe.
The whole article just seems to be anecdotal and full of straw men. If it was written in jest then the humor was lost on me.
- kyllo 12y agoAs Peter Norvig famously said, "Design patterns are bug reports against your programming language." Read his presentation on why the most common design patterns become simpler or even unnecessary when using a dynamic functional language such as Lisp: http://norvig.com/design-patterns/ http://norvig.com/design-patterns/
- debacle 12y agoWhether a design pattern is implicit or explicit is a matter of preference. Personally, I prefer to make my design patterns explicit even when working in languages that don't require that convention because it makes my code easier to grok for others. Edit: Thomas, I can't reply since this has been flagkilled, but for you or I an implicit pattern is superior. That said, many business programmers don't come from a functional background and for those programmers I prefer to make my code easier to read.
- tptacek 12y agoCan you give a couple examples of pairs of patterns and native language implementations where the explicit pattern invocation is clearer and easier to grok? Norvig's simplest example is "factories" in languages where classes are already first-class and can be passed around without extra machinery. Clearly, Norvig is right about that one.
- vinceguidry 12y agoThe one I think of off hand is the Registry Pattern. A Registry is a collection of objects or classes that need to be globally accessible. You can't just attach state anywhere in Java, so you create Registry classes to hold all of them. But in Ruby, you can define instance variables on class objects, so that's where I put my registries. Let's say I have a custom logging class, named Logger, and I have three different logs that need to be accessed. What I would do is define self.[] on Logger, that accesses @loggers on the Logger class itself. So whenever I need a file logger, I just call Logger[:file] rather than LoggerRegistry.get_logger(:file) Note that an instance variable on a class is different from a class variable. A class variable in Ruby is shared across the all the descendants of the class, and up the chain too to a point. (I don't think they go all the way up to Object but I'm not too clear on the details there.) In practice class variables are rarely used. For the Factory pattern, the usual way to do it is to define a .create or .build method on the superclass, and have it return or define the needed class. If it were me, I'd use .create to make objects, and .build to make classes.
- kyllo 12y agoA Registry is a collection of objects or classes that need to be globally accessible. This is a variation on the "Singleton Pattern" and IMO it is an antipattern. It tightly couples your classes to a "global state" class which makes unit testing very difficult. This is why Dependency Injection was invented. And in Lisp-like languages DI is totally trivial due to having first-class functions and closures.
- vinceguidry 12y agoWell, the coupling is there whether you're using DI or a Registry, it's just a question of where the code expects its dependency to be. In DI, the dependency is passed in as part of the sets of arguments, in a Registry, it expects it to be somewhere else. What I like about using a class object to hold the state is that the class is being depended on anyway, so you're not introducing any 'extra' coupling. I also like to allow the dependency to be passed in as an argument, with the default being to grab it out the registry, for testing purposes or in case I'm hooking into the code with a REPL for whatever reason. This way you get the benefits of DI without littering your classes with keyword arguments that, 99% of the time are only going to interact with one thing.
- kasey_junk 12y agoThe problem with the term "pattern" is that it has 2 different meanings: 1) a guide for how to build/create something. 2) a describable and characteristic arrangement. Both can be applied to "design patterns". ie, I'm going to solve a code reuse problem, should I use the strategy or template pattern. Or I'm going to solve this code reuse problem in a novel way in my inheritance based language. I know I'll make an abstract base class that does the reusable stuff and uses some abstract methods to fill in the changing stuff. So really when people say that "design patterns" are bad, what they really mean are 1) the GoF patterns are only necessary because your language is flawed or 2) people are picking the wrong patterns to solve problems. But all languages and software systems have patterns, they just might not be cataloged in GoF.
- olavk 12y agoYeah, OO design patterns are typically not relevant in functional languages, but functional languages have their own share of patterns.
- uglycoyote 12y agoOh, there are patterns in LISP as well, such as this one: ))))))))))))))))))))))))))
- Eleopteryx 12y agoThat part of the article is where I stopped reading.
- king_magic 12y agoI agree. Let's imagine writing a compiler without the visitor pattern. In fact, hey, let's go a step further and build one in a functional language. I'd be willing to put money down that the strategy that would evolve for say, code generation, would look a hell of a lot like - wait for it - the visitor pattern. To your point, OO & design patterns aren't necessarily intertwined.
- lmm 12y agoThe double-indirection of the visitor pattern is unnecessary in a language with pattern matching. I mean sure, it's just syntax, just sugar - but readability is important. As the saying goes, a design pattern is a structured way of working around a language deficiency.
- king_magic 12y agoI agree, but I'd argue that double-indirection isn't really a defining characteristic of the visitor pattern. In fact, I'd argue that the visitor pattern is really one of the most "functional" patterns there is.
- TillE 12y agoQuite. It should be obvious how to implement it using std::function and lambdas in C++, for example. Having a bunch of polymorphic classes is an ugly implementation detail, not the essence of the pattern.
- deleted 12y ago[deleted]
- j_jochem 12y agoFrom what they taught me at software engineering 101, double dispatch is exactly the point of the visitor pattern. If your instance of Visitor lacks double dispatch, that means it's just a very complicated way of performing external iteration on Composites.
- pacala 12y ago
- mcphage 12y ago> Is this article a joke? For the most part, yeah—hence why it was given as a keynote an an OOP conference. Or to look at it another way—this was a critique from a practitioner of OOP, speaking to other practitioners of OOP, not a critique from someone outside looking in.
- dragonwriter 12y ago> A design pattern demonstrates a solution to a common programming problem! That's true, but the recipe style presentation and implementation of design patterns demonstrates a common problem with programming languages -- lacking sufficient expressiveness to implement a general solution as reusable library code. However, there is nothing really special about OOP here except that the industrial popular languages at the time when documenting "design patterns" (using that name), including implementation recipes, as a solution for recurring problems to which library code wasn't an adequate solution happen to be statically-typed, class-oriented, OO languages. Somewhat similar things existed prior to OO dominance, though the adoption of the "design pattern" term and some of the structure of typical description from architecture hadn't happened yet.