Debasish specializes in leading delivery of enterprise scale solutions for various clients ranging from small ones to Fortune 500 companies. He is the technology evangelist of Anshin Software (http://www.anshinsoft.com) and takes pride in institutionalizing best practices in software design and programming. He loves to program in Java, Ruby, Erlang and Scala and has been trying desperately to get out of the unmanaged world of C++. Debasish is a DZone MVB and is not an employee of DZone and has posted 55 posts at DZone. You can read more from them at their website. View Full User Profile

Design Patterns - The Cult to Blame?

11.10.2008
| 7806 views |
  • submit to reddit

I always thought that the GOF Design Patterns book achieved it's objective to make us better C++/Java programmers. It taught us how to design polymorphic class hierarchies alongside encouraging delegation over inheritance. In an object oriented language like Java or C++, which does not offer first class higher order functions or closures, the GOF patterns taught us how to implement patterns like Command, Strategy and State through properly encapsulated class structures that would decouple the theme from the context. As long as we do not link them with the pattern definition and theory as espoused by Christopher Alexander, the GOF book has an invaluable contribution towards today's mainstream OO community.

But that's only the good part. I was wondering what made many people cringe at the patterns movement that seem to deluge the programming community for well over a decade.

One of the drawbacks that the pattern movement in the programming community suffered from, was that, the design patterns as promoted by the GOF book, focused too much on the implementation aspects, the how part of the solution, instead of the what part of problem that they solve. This resulted in the implementation language being the main focus of the entire pattern. People started thinking that C++ is the language of choice since all of the GOF design patterns can be implemented faithfully using the honored constructs of the language. And, of course, in due time, Java, positioned as a better C++, also inherited the same honor. It may not be totally coincidental that during the time we were busy adulating the virtues of GOF design patterns in Java and C++, development of newer programming languages were at a very low ebb.

Developers started thinking that Java and C++ are the be-all and end-all of programming language implementations, since we can implement all GOF patterns in them. Enterprise software loves to follow common practices, rote techniques that can be easily replicated through a set of replacable programmers, and the combination of Java and design patterns made a perfect match. Switching languages was difficult, and even for some mainstream programmers today, switching to more powerful languages like Ruby or Scala, the initial thought processes were limited to the abstraction levels of Java. In reality, the patterns movement created a cult and made us somewhat myopic towards implementing higher order abstractions even in any other more powerful programming language.

Mark Jason Dominus reiterated this way back in 2006 ..

"If the Design Patterns movement had been popular in the 1980's, we wouldn't even have C++ or Java; we would still be implementing Object Oriented Classes in C with structs, and the argument would go that since programmers were forced to use C anyway, we should at least help them as much as possible."

Are Design Patterns useless ?

Absolutely not. Patterns are solutions to problems in context. As long as the problems remain, patterns remain equally relevant. What we need to do is highlight on the intent of the pattern, the problem that it solves, the forces that it resolves and the resultant forces that it generates, instead of just documenting how it solves it in one particular language.

As an example, the Strategy pattern is intended to decouple the implementation of an algorithm from the context of the application. In case of Java, it is implemented through the context class delegating the responsibility to the strategy interface, that can have multiple implementations. Looks and sounds ceremonious, but that is what it is, if you use Java as the implementation language. In languages that support higher order functions, the same pattern is implemented much more succinctly using native language features. Hence the implementation is subsumed into the natural idioms of the language itself. Again, if we highlight on the intent of the pattern, it remains *equally relevant*, irrespective of whether we use Ruby, Groovy, Scala or Lisp for implementation. And the intent is loud and clear - the implementation of the algorithm is a separate concern than the concrete context to which it is being plugged into.

Similarly, the Visitor pattern has often been maligned as an overtly complex structure that should be avoided at any cost. Visitor looks complex in Java or C++, because these languages do not support higher order abstractions like pattern matching or multiple dispatch mechanisms. Languages like Scala that support pattern matching have been known to implement succinct visitors without much ceremony. This paper, presented in OOPSLA 2008, implements the Visitor pattern as a reusable generic type-safe component using the powerful typesystem of Scala.

Irrespective of how you implement, Visitor remains a potent solution to the problem of separating the structure of abstraction hierarchies from the behavior of traversals over that hierarchy. The important part is to add the intent of Visitors to your design vocabulary - it is just the level of abstractions that the language offers that makes the implementation invisible, informal or formal.

Many people also talk about Singleton implementation in Java as being too elaborate, complex and unnecessarily verbose. On the other hand, singleton is available as a library call in Ruby and as a single word language syntax in Scala. That does not make Singleton a simpleton, it is just that Java does not offer a sufficiently higher level of abstraction to express the intent and solution of the pattern. Go, use dependency injection frameworks, they offer Singletons as configurable behaviors ready-to-be-wired with your native objects.

Patterns as a vehicle of communication

.. and not as code snippets that can be copy pasted. The real intrinsic value of design patterns is that they facilitate communication in processes by encouraging a common vocabulary and format that binds the design space. Coplien mentions in his monograph on Software Patterns ..

"Besides, we believe that human communication is the bottleneck in software development. If the pattern literary form can help programmers communicate with their clients, their customers, and with each other, they help fill a crucial need of contemporary software development.

Patterns are not a complete design method; they capture important practices of existing methods and practices uncodified by conventional methods. They are not a CASE tool. They focus more on the human activities of design than on transformations that can blindly be automated. They are not artificial intelligence; they celebrate and encourage the human intelligence that separates people from computers."

People, mostly from the dynamic language community, frown upon design patterns as being too ceremonious, claiming that most of them can be implemented in dynamically typed and functional languages much more easily. Very true, but that does not undermine the core value proposition of design patterns. Maybe most of us became converts to a cult that focused too much on the implementation details of the patterns in a specific family of languages. Ideally we should have been more careful towards documenting beautiful patterns and pattern languages as the core vocabulary of designers.

Some people on the Erlang mailing list recently talked about OTP being the embodiment of Erlang design patterns. OTP is clearly a framework, that helps develop highly concurrent client server applications in Erlang. Patrick Logan correctly points out that OTP is a collection of patterns, only in a very poor sense of the term. The real collection would be a pattern language that documents the problems, identifies the forces at play and suggests solutions through a catalog of literary forms that will help develop concurrent server applications from ground up. In case of Erlang, gen_server, gen_event, gen_fsm etc. collaborate towards implementing the pattern language. Similar efforts have been known to exist for Scala as well. Implementing the same in any other language may be difficult, but that will only point to the deficiencies of that particular language towards implementing a concrete instance of that pattern language.

From http://debasishg.blogspot.com/

Published at DZone with permission of Debasish Ghosh, author and DZone MVB.

(Note: Opinions expressed in this article and its replies are the opinions of their respective authors and not those of DZone, Inc.)

Comments

Norman Villatoro replied on Mon, 2008/11/10 - 12:19pm

Patterns are useful but like anything else, too much of a good thing is bad. Regularly I run into cases of pattern overload where the "software engineer" did not so much do a design but tried to beat the world record of how many patterns can be applied to any given problem.

Their defense for their over-engineered designs is usually "Well, if we change databases, application servers etc." Maybe for a product developer or for a start-up, but in corporate America (and probably the rest of the world) change does not come often. I'll take the simplified design thank you very much.

BTW I think we used to call them algorithms.

Leonid Maslov replied on Mon, 2008/11/10 - 1:13pm

I _partly_ agree. If the GOF would use Lisp or python insted, would you still argue? I doubt it. Any logically reasoning programmer understands that patterns are not about code, but are about design. (As far I remeber from reading that book, the GOF team insisted on that, at least at all the their articles about it).

Maybe it's woth to create some "Dynamic language pattern"books or smth. But the whole article reminded me "Only Lisp for AI" etc articles (because all good books about AI I could find used Lisp or Prolog, and it MADE  many programmers to think these are the only languages to work in that area. It depends on each concrete programmer, his education and his vision.)

 So, it would be very nice if someone would port all these patterns to some other language, describa them nicely etc and outsource (OSS) version of "Ruby GOF Patterns" or "Lisp GOF Patterns" books. We all would benefit from that, but I doubt the real problem lies there.

Alex Miller replied on Tue, 2008/11/11 - 10:32am

You're speaking my language man.  This is exactly the point and focus of my talk Design Patterns Reconsidered which you can find here:

Design Patterns Reconsidered

I think if the GoF had called the book "Design Problem Patterns" that might have changed the focus a bit on identifying common problems and then discussing the many possible solutions/variations of those problems.  In some cases, the problem is addressed directly in a language feature.  But the problem (say the "expression problem" defined by Wadler addressed by the visitor pattern) continues to exist and need a solution, whether it's in the language or not.

 

Silvio Bierman replied on Wed, 2008/11/12 - 3:58am

In my opinion the design pattern book has been misread by most people. It shows us a number of abstract problem cases and ways to implement proposed solutions in a structured way. As such it is a very valuable book for learning how to analyse practical design problems and translate them to sound code structures.

Instead most people seem to think they have to keep using exactly the patterns that are presented in the book. They use it as a handy toolkit and try to mold each programming problem into one or several of the holy patterns. Althoug many of the patterns are very generic and can be applied in numerous cases I think programmers should try to develop the ability to create optimal constructs for any problem instead of just memorizing "the patterns".

Whenever I hear a programmer calling out this situation just needs some Singletons combined with a couple of Visitors I tend to disconnect.

About the programming language: I think that within boundaries the programming language of use is irrelevant to problem analysis. Coming up with good solutions is hard, mapping them to a specific language is easy.

 

Leonid Maslov replied on Wed, 2008/11/12 - 5:34am

Exactly my thoughts (In more structured way they use to be in my head) 

Comment viewing options

Select your preferred way to display the comments and click "Save settings" to activate your changes.