Featured in
Architecture & Design

Mini-talks: The Machine Intelligence Landscape: A Venture Capital Perspective by David Beyer. The future of global, trustless transactions on the largest graph: blockchain by Olaf Carlson-Wee. Algorithms for Anti-Money Laundering by Richard Minerich.

Featured in
Process & Practices

In-App Subscriptions Made Easy

There are various types of subscriptions: recurring, non-recurring, free-trial periods, various billing cycles and any possible billing variation one can imagine. But with lack of information online, you might discover that mobile subscriptions behave differently from what you expected. This article will make your life somewhat easier when addressing an in-app subscriptions implementation.

Featured in
Operations & Infrastructure

Mini-talks: The Machine Intelligence Landscape: A Venture Capital Perspective by David Beyer. The future of global, trustless transactions on the largest graph: blockchain by Olaf Carlson-Wee. Algorithms for Anti-Money Laundering by Richard Minerich.

Featured in
Enterprise Architecture

Mini-talks: The Machine Intelligence Landscape: A Venture Capital Perspective by David Beyer. The future of global, trustless transactions on the largest graph: blockchain by Olaf Carlson-Wee. Algorithms for Anti-Money Laundering by Richard Minerich.

Gang of Four Design Patterns - Does it stand the test of time?

More than a decade ago by Erich Gamma, Richard Helm, Ralph Johnson and John Vlissides known as the Gang of Four (GoF) published their seminal book "Design Patterns: Elements of Reusable Object-Oriented Software". The GoF book, which is considered the harbinger of the whole software patterns movement, has recently been criticized as no longer relevant, solving problems which are better handled by newer languages and introducing needless complexity.

1. Design patterns are a form of complexity. As with all complexity, I'd rather see developers focus on simpler solutions before going straight to a complex recipe of design patterns. 2. If you find yourself frequently writing a bunch of boilerplate design pattern code to deal with a "recurring design problem", that's not good engineering-- it's a sign that your language is fundamentally broken.

Steve Rowe agrees that the patterns should be used as examples of good design and principles to apply and not as a reference book but he says that Jeff is off the mark because he attacks the concept instead of the way where the blame is on the people who apply them wrongly. He concludes that patterns should be treated as examples for good design not as dogma:

Design patterns are very useful when we study how they work so we can create similar patterns. They are bad when we try to copy them directly. If one reads the Gang of Four, he will realize that the authors often give several examples of each pattern and they're all slightly different. One might also notice that there is a lot of talk about the OO concepts that lead to the patterns.

Cedric Otaku answers both Jeff and Mark's criticism in a post he called "In defense of Design Patterns". Cedric says that Jeff (and Mark before him) are wrong for criticizing the GoF book, without offering any alternative. Cedric, goes on to explain the problem with making a parallel between Alexander's construction design pattern and software design patterns

There is a reason why it's important to establish a clear separation between Alexander's Design Patterns and the GOF's Design Patterns: software engineering is nowhere near as advanced as building engineering is. We are still working on these nuts and bolts, and whenever a new software project starts, we still can't be sure it won't collapse under its own weight after just a year. To make a parallel: imagine a world where every time a new construction takes place (say, a bridge), the future of that bridge depends on the team of engineers and workers you choose to build it...

Cedric says that because construction is far more advances (in its predictability and stability) than software is. we are still struggling for the basics and we should be focused on that.

On the other hand a Aristotle Pagaltzis left a comment on Cedric's blog and rationalized Mark's critisism

Dominus says that design patterns are a sign of a deficiency of a language for the purpose that the design pattern addresses. In other words, the Visitor pattern used in Java points to the fact that Java is deficient in terms of list processing: the `map` and `filter` constructs need to be emulated with lengthy OO incantations.

He is _not_ saying that the use of design patterns _as such_ is bad. He is saying they are a sign of a deficiency.

It seems most (if not all) agree that patterns as tool in software engineering is useful, the debate is on the value of the GoF book today. What do you think ? is the Gof Design Patterns a timeless piece or has it outlived its purpose ?

I find the GoF design patterns book very useful, especially the first section that cautions against common pitfalls such as overuse of inheritance. I think it should be read by anyone who's serious about building software. But I've also seen people go to lengths to force a pattern on a problem that didn't need it, adding needless complexity. I would rather arrive at the simplest design through continuous design and refactoring, then use the vocabulary the GoF book introduces to describe the solutions when applicable.

I think people have been way too fixed on the details of this book, when the whole picture is what it is important. This book displays how a design is made based on a problem identified. And promotes the identification of patterns in YOUR application. I don't think the GoF was ever intended as a recipe book, but more as a guided tour of the solution to a problem.

This whole talk about 'the use of patterns says the language is broken' is pointless.

For example, Ruby's standard APIs use the Visitor pattern extensively. It's not just because it is built in the libraries that it's not there. If you are going to build a text editor in Ruby, you probably will use the Flyweight pattern. It's not built in the standard APIs (I don't know, it's just an example), so Ruby sucks?

Sure, new languages incorporate into their APIs patterns that proved to be useful in the past. But as any design choice, it's a trade-off. Adopting one way to do things will always exclude other ways, which could fit better in some specific context. And then you'll have to work around it, and you'll probably create some kind of design pattern to do it. Then, your language is broken? Or maybe you'll want to create a new language to solve every single problem that your current language/libraries are not optimized for?

Design patterns are common solutions to recurring problems, a very good way to document knowledge, and a nice way to develop a high-level vocabulary. You can use it well or not, but it all depends on you, not on some black magic created by the GoF guys.

Totally agree with you. A language can't answer all your questions out of the box. Design patterns are way of doing things (better ways of doing things). They defined common problems and propose solutions for them. There will be new problems in the future, different problems. What happens then? I think languages give you the tools you are free to follow whatever road you choose..

Sure, the GoF patterns and others are here to stay. They are a sign of a maturing industry: it´s old enough and conscious enough to realize that solutions are recurring and that some solutions work better than others. On the class level the GoF patterns are a compilation of such successful solutions. Great!

But that does not mean, these patterns need to be adhered to slavishly. And it does not mean, they are the new building blocks to use to put together new applications. If you detect a situation of a certain kind, you certainly should check the GoF patterns for a solutions. But don´t start your next project by asking "What patterns should we glue together?"

Components are building blocks on a much needed higher level of abstraction than classes. GoF patterns are not.

I guess I'm not sure what his point is. Is he saying that we should all drop developing in Java or C++ because they require patterns that Ruby might not?

Quote:

If you find yourself frequently writing a bunch of boilerplate design pattern code to deal with a "recurring design problem", that's not good engineering-- it's a sign that your language is fundamentally broken.

He's right that some design patterns are required because of a deficiency of the language, but what's the alternative???

I think the book is still useful - mostly. However, there is one pattern that has probably caused more harm than good, and that's the Singleton pattern. It is, in my book, an antipattern, because it leads to very tightly coupled code that is hard to test, at least in statically typed languages like Java and C#. Dependency Injection is a great alternative to Singleton that elminates Singleton's coupling and test unfriendliness.

I don't blame the GoF for including it - Testing, TDD and mocking was not on the agenda when the book was written. But people reading the book today should be aware of what patterns are obsoleted by more modern patterns (or design principles).

He's right that some design patterns are required because of a deficiency of the language, but what's the alternative???

Low level design patterns (e.g. those in GoF) can mostly be codified or melted away at relatively higher abstraction levels (and will be replaced with higher level design patterns). There are some commonly used alternatives and/or techniques for this kind elevation (even without droping the low level programming languages) such as:

The alternative is more expressive languages. Eventually we will drop development of Java and C++ applications. Hopefully the replacement language will be more expressive, something that obivates most of the GoF patterns. The questions are what is this next language and how soon can we make the transition? Personally, I'm tired of the Java handcuffs.

The alternative is more expressive languages. Eventually we will drop development of Java and C++ applications. Hopefully the replacement language will be more expressive, something that obivates most of the GoF patterns. The questions are what is this next language and how soon can we make the transition? Personally, I'm tired of the Java handcuffs.

There are many such languages already, even before the GoF book and the Java language. In fact, the issue of expressiveness of language vs design patterns isn't a new topic, but has been well known among functional programming (FP) folks for years. Even the GoF book itself published more than a decade ago (not recently and before Java) also pointed out (page 4) that design patterns are relative to the choosen language. For instance, the factory pattern is largely vanished in Ruby and FP languages and the visitor pattern is less needed in CLOS (much older than Java), the iterator is internal in FP, the ....

There are many discussions much objective than the exaggerated opinions in the cited articles. For instance, Matthias Felleisen pointed out in his "On the Expressive Power of Programming Languges" article published in 1991 (many years before GoF and Java):

* By studying a number of examples, we have come to the conclusion that programs in less expressive languages exhibit repeated occurrences of programming patterns, and that this pattern-oriented style is detrimental to the programming process.

* Based on these examples and others with a similar flavor, we have come to believe that the major negative consequence of a lack of expressiveness is the abundance of programming patterns to make up for the missing, non-expressible constructs.

* Programs in more expressive programming languages that use the additional facilities in a sensible manner contain fewer programming patterns than equivalent programs in less expressive languages.

However, all of these by no means suggest that expressiveness should always be the sole pursuance of a programming language. Rather, it should be one of many trade-off factors to be considered by language designers. Blindly increasing the expressiveness of a generic language to eliminate design patterns not only could sacrifice application runtime efficiency but also could undermine the language's intuitiveness, simplicity, legacy compatibility, and more importantly its application code maintainability.

For example, Ruby's standard APIs use the Visitor pattern extensively. It's not just because it is built in the libraries that it's not there. If you are going to build a text editor in Ruby, you probably will use the Flyweight pattern. It's not built in the standard APIs (I don't know, it's just an example), so Ruby sucks?

Ruby does make the factory pattern largely vanished and therefore consider to be more expressive than C++. The visitor pattern, although not completely being eliminated, is indeed less needed in certain languages (such as CLOS -- as GoF pointed out in page 4) and/or under the help of a framework on top of a language (e.g. Java) that supports reflection and dynamic proxy.

I believe like a lot of methodologies & technologies they get used and abused when they aren't the best solution for the problem.

This is the case with the GoF book in my opinion, I have seen on more than one occasion the liberal use of patterns in projects that blatantly don't need it, i.e. the use of factories that creates instances of only one known type, the implementation of a the observer pattern when it has already been implemented by the framework (.Net events).

To me this shows that the average developer has 'evolved' and learnt that they should be using patterns but not really understanding there power - they believe that implementing patterns (everywhere) makes the software intrinsically better.

I say these Morts have evolved :)

This doesn't mean to me the GoF is no longer as important it just means our understanding of patterns is more mature.

The alternative is more expressive languages. Eventually we will drop development of Java and C++ applications. Hopefully the replacement language will be more expressive, something that obivates most of the GoF patterns. The questions are what is this next language and how soon can we make the transition? Personally, I'm tired of the Java handcuffs.

There are many such languages already, even before the GoF book and the Java language. In fact, the issue of expressiveness of language vs design patterns isn't a new topic, but has been well known among functional programming (FP) folks for years. Even the GoF book itself published more than a decade ago (not recently and before Java) also pointed out (page 4) that design patterns are relative to the choosen language. For instance, the factory pattern is largely vanished in Ruby and FP languages and the visitor pattern is less needed in CLOS (much older than Java), the iterator is internal in FP, the ....

There are many discussions much objective than the exaggerated opinions in the cited articles. For instance, Matthias Felleisen pointed out in his "On the Expressive Power of Programming Languges" article published in 1991 (many years before GoF and Java):

* By studying a number of examples, we have come to the conclusion that programs in less expressive languages exhibit repeated occurrences of programming patterns, and that this pattern-oriented style is detrimental to the programming process.

* Based on these examples and others with a similar flavor, we have come to believe that the major negative consequence of a lack of expressiveness is the abundance of programming patterns to make up for the missing, non-expressible constructs.

* Programs in more expressive programming languages that use the additional facilities in a sensible manner contain fewer programming patterns than equivalent programs in less expressive languages.

However, all of these by no means suggest that expressiveness should always be the sole pursuance of a programming language. Rather, it should be one of many trade-off factors to be considered by language designers. Blindly increasing the expressiveness of a generic language to eliminate design patterns not only could sacrifice application runtime efficiency but also could undermine the language's intuitiveness, simplicity, legacy compatibility, and more importantly its application code maintainability.

for those who DO NOT GET objects. If you're starting to learn OOP than GoF is one book you should read. Complemented by a much more practical one which is Domain Driven Design (Evans), one for algorithms (Dasgupta will be more than fine) and now, with all this Amdahl stuff, one for concurrent programming (if going with java them see the book by Goetz et all) and you can start programming w/o doing too much harm to the industry :-).

However GoF has the biggest impact after you spend several years writing broken OO code :-D