Should I use a design pattern?
Ezra Schwepker
Posted on June 10, 2019
Yes. And no. Maybe?
Design patterns like Flyweight or Facade each serve purpose and a reason for being. Each pattern is named, formalized, and put forth as a best practice. But if we treat them as formal structures which we cannot stray from, we limit ourselves and lose sight of how design patterns are created.
The key word isn't design, it's pattern. Design patterns are recognized. They are the convergent evolution of solutions to issues arising within Object Oriented programming. As you develop as a programmer, you will likely run into the same issues that generated a particular pattern and find yourself arriving at similar solutions.
A design pattern isn't invented in a crystalized, perfect form, it is consolidated from a multitude of similar approaches. It serves a purpose, and offers a recognized solution to a particular set of problems, but it can also be expressed in a number of different ways beyond a rigid example in a hefty book.
Design patterns are important, not just because they offer a recognized best practice approach to a specific issue, but also because they provide us a shared vocabulary which we can use to discuss abstractions of our code, free of any implementation details.
However just because a design pattern has been recognized and agreed upon and recorded, does not mean that that particular pattern is still worth implementing. Programming trends and language capabilities do change over time, and as a consequence, the problem set addressed by a particular pattern may have shifted or been addressed.
Delay Using Them
Patterns, like all forms of complexity, should be avoided until they are absolutely necessary. That’s the first thing beginners need to learn. Not the last thing.
While I can't find the source of that quote, aside from a comment here, there's a ring of truth to it. Many of the reductions of complexity made possible by a design pattern are only made necessary if we have arrived at that level of complexity to begin with.
Novice programmers often make the mistake of reaching for a pattern, or two, or all of them, and end up with a bloated, tangled mess. Using a pattern does not make your code better, unless you are using it appropriately. Even then, you may have arrived at a situation prompting using one because of the consequences of an earlier choice.
"Always implement things when you actually need them, never when you just foresee that you need them." - Ron Jeffries
Don't reach for a solution until you've encountered and defined the scope of a problem. Designing towards a pattern rather than arriving at one in response to the needs of your system will simply add cruft. Instead, refactor towards an appropriate pattern, if any while keeping your code SOLID and DRY.
Weigh the Cost
Something I appreciate greatly about the standardized format of design patterns is that each one must detail not only when it is useful and how to implement it, but also the tradeoffs.
For example, the Flyweight Pattern, which is designed to avoid unnecessary initialization, reducing resource cost:
moving the state outside the object breaks encapsulation, and may be less efficient than keeping the state intrinsic. In these cases it may be necessary to decide whether performance or memory is more important.
Flyweights are based on pointers or references. Working with Flyweights is easy in a language like Java where all object variables are references and a garbage collector is responsible for removing old objects. Flyweights are just a little trickier in a language like C++ where objects can be allocated as local variables on the stack and destroyed as a result of programmer action.
Singletons have been widely criticized and, depending upon the language, may not even be necessary, and require convoluted implementation.
Implement Concepts not Snippets
Using snippets or copy-pasted code that someone else wrote is a great way to save time. It's also a great way to end up with code that you don't personally understand or relate to to the degree that you would if you implemented it yourself.
Grok the what and the why, rather than pasting the how. Pasting in a finished pattern skips over the stages of evolution that bring you both the understanding of why it exists and how it works. A pattern has been refactored many times before it reaches a formalized state. Arriving at it will ensure that you have some of the same experiences that motivated your peers, rather than depending upon their wisdom.
Conclusion
Should you use Design Patterns? Absolutely! Should you memorize them? Maybe. Should you be familiar with them? Certainly. Should you implement them without a clearly defined need? No.
Refactoring Guru: Design Patterns
JavaScript Design Patterns
Refactoring Patterns
Posted on June 10, 2019
Join Our Newsletter. No Spam, Only the good stuff.
Sign up to receive the latest update from our blog.