This site will look much better in a browser that supports web standards, but is accessible to any browser or Internet device.

Anomaly ~ G. Wade Johnson Anomaly Home G. Wade Home

October 01, 2014

BPGB: Pattern Mania

This is yet another in the Best Practices Gone Bad series of posts.

Around two decades ago, the book Design Patterns (often called the Gang of Four, or GoF, book) was published. This book introduced a large number of programmers to a new approach to thinking about solutions.

For those who are not familiar with Design Patterns, you can think of a pattern as a high-level description of a generalized solution to a standard problem. A pattern has a standard name, a problem, a solution, side effects, and a list of other patterns that work with it.

Pattern Advantages

Many programmers focused on the 23 solutions to real world problems that the book provided. For some programmers, these solutions supplied answers to problems that they had struggled with. Some of the solutions covered problems that the programmers had not even realized they needed to solve.

However, one of the most useful features of patterns is the language and names they define. Most of the patterns were actually solutions many people had used at one point in time or another. Before the Design Patterns book, two developers from two different projects would likely name almost identical solutions differently. These two developers might not able to talk intelligently about their solutions if they did not realize that they were implementing the same solution. After Design Patterns, it became easier to recognize similar solutions because we had standard names.

If the developer actually read the Design Patterns book, their solution may even be better because the book lists consequences of a pattern. This should give the developer more information to improve their design. In particular, the developer can make certain that the defined consequences do not cause problems with the rest of the system design.

Pattern Over-Use

As expected, when people first realized the power of Design Patterns, they began to use them everywhere. This seems to happen pretty much anytime a developer discovers a new technique or paradigm. There was a running joke for a while about novices trying to fit all 23 patterns from the book into a Hello World program.

Right about the same time that Design Patterns was taking off, Java began to become popular. Many Java programmers incorporated Design Patterns into their fundamental understanding of OOP and Java best practice. Thanks to Sun's marketing muscle, Java got a lot of air time around business people, which resulted in a number of University Computer Science programs choosing Java as the first language for CS students. These three items caused many junior programmers to get the idea that a program that uses patterns is a good program and one that doesn't is a bad program.

Unfortunately, this ignores the fact that the original purpose of Design Patterns was to describe common solutions. It explicitly explained the problem that a pattern was intended to solve. Unfortunately, many of these junior programmers assume that their program will need to have a Factory or Visitor (for example) before even considering if the problem calls for any such thing. This leads to a joke I've seen recently on-line:

I had a problem, so I decided to use Java. Now, I have a ProblemFactory.

At this point, I need to make perfectly clear that the pattern over-use problem is not an inherent problem with the Java language. It's really a side effect of the two becoming popular at the same time and Universities adopting the language while the hype was high. Many senior Java programmers do not make this mistake. They carefully consider patterns just like any other important design decision. But, junior programmers sometimes make the mistake of starting their design by deciding which patterns to apply before they have determined what will be needed.

The Singleton

One pattern from the GoF that has been especially problematic has been the Singleton. Part of the problem is that the pattern describes a class with two responsibilities: object lifetime and object access. This is probably a valid criticism, since the other patterns in the book definitely are more single responsibility solutions.

The bigger issue, that has raised the ire of many programmers, is that an inexperienced programmer may use the Singleton pattern to legitimize what is nothing more than global data. Global variables have been recognized for decades as an ongoing source of problems in code. If the variable can be changed, you are pretty much guaranteeing action at a distance bugs where one piece of code changes the global state and another depends on the old value. (Note that this issue only applies if the object's state is mutable. If you can't change the object's internal state or affect it's behavior, there's no action at a distance problem.)

Honestly turning the GlobalKitchenSink object into the GlobalKitchenSinkSingleton does not improve code. But many inexperienced programmers feel that, since the Singleton was blessed by the GoF, global data expressed as a Singleton is fine. Since these programmers have likely never maintained a system using global data or dealt with the troubleshooting problems, they misuse this pattern just like they would have used the global data. Since they don't have the scars of fighting global data, these inexperienced programmers embedded Singletons (sometimes God Object Singletons) in their code. And they feel justified, because Singleton is a blessed pattern.

A secondary issue is the coupling between many pieces of code in the system and this Singleton. Testing is harder because classes depend directly on a Singleton object that we can't control. We can't easily subclass the Singleton to provide more control or functionality, because every place it's used, the name of the class is used directly. This introduces a high degree of coupling into the system that may not be necessary.

Conclusion

When the Design Patterns book came out, some developers believed that having good names, terminology, and examples would help junior programmers do much better design. Unfortunately, like all good ideas, patterns turned out not to be the silver bullet we were looking for. Since some people decided that design patterns meant good design, they immediately concluded that more design patterns must mean even better design.

Posted by GWade at October 1, 2014 03:00 PM. Email comments