April 11, 2016
Relearning Design Patterns
—Abusing design patterns by misapplying them.
In Relearning Design Patterns
, Egon Elbre observes that a critical piece of information is missing from Design Patterns: Elements of Reusable Object-Oriented Software
is a pragmatic outlook on how and when to apply design patterns. Egon points to Christopher Alexander and his idea of pattern languages as a solution.
Pattern languages have the benefit of describing a system of patterns that support each other. It's a nice approach that has the potential to clarify when, and perhaps more importantly, when not to use a design pattern.
For example, the code I work with has a high occurrence the Singleton pattern. No other patterns are made explicit, except possibly Model-View-Controller. My challenge is that our design uses the Singleton to present one of something because there currently is only one of those things. The use of a Singleton introduces constraints that shouldn't be in the design.
If our code base modelled an airplane, it would have a singleton for the engine on a single engine plane, completely ignoring the fact that many planes have more than one engine. The Singleton places an arbitrary constraint on the design where none should exist and this introduces needless complexity into our domain.
In my view, the designers didn't view the domain in terms of appropriate and inappropriate constraints. Our implementation is the poorer for it. If they viewed the domain in terms of a pattern language they may have realized that using a Singleton for a jet engine assumes there will only ever be one engine. They may have recognized that a jet plane has the potential to support multiple engines. Recognizing this would have identified the Singleton as a poor design choice.
A classic case of when all you have is an idiom everything looks like and instance of it. Or perhaps that was a hammer.
In another example, I've recently had the opportunity to build a client-side library for a web application. At one point, I played with the notion that that a Singleton would be appropriate for managing the client session with the server. My initial rationale for this was that I knew
the client would be run as a standalone application by a person using it on the command-line.
I ultimately rejected the Singleton because it placed an arbitrary constraint on the client-side library. I recognized that it's presence in the implementation would guarantee I limited the use cases supported by this library.