Most software engineers will, sooner or later, learn about design patterns. Or at the very least, hear wind that design patterns are an important arsenal in a software engineer’s toolbox.
A design pattern isn’t really something tangible you can pluck off a store shelf. It’s not a piece of reusable code or library that you can incorporate in your software project, either.
It’s more a way of thinking about a problem and coming up with a “plan of attack” in the way you go about finding an efficient solution to that problem.
Design patterns certainly didn’t pop into existence overnight. They were forged out of the trenches of software development, through many years of hard-won experiences, lessons learned, learning from mistakes and sharing those same tribal learning experiences with other developers.
Over time, a set of formalized design patterns were created by four engineers known as the “Gang of Four” (Erich Gamma, Richard Helm, Ralph Johnson, and John Vlissides). They codified their list of design patterns in their book, “Design Patterns: Elements of Reusable Object-Oriented Software”.
So what problem do design patterns solve?
In a nutshell … CHANGE.
Software Never Stands Still
Software is always in a constant state of evolution. Version 1.0 of a piece of software is never complete. Microsoft didn’t just release the first version of their Windows operating system at version 1.0 and dust off their hands and call it done. They didn’t release a version 1.0 of their Office product and call it done either.
Microsoft continues to update and evolve their software products in response to customer requests.
It doesn’t just happen by magic.
It requires careful analysis, planning and line by line source code changes.
The problem lies in the act of changing your source code. When you change something in your code, those changes can cause unwanted breaking changes to other places in your source code.
The technical explanation for why this happens, in the object oriented programming world, is that code is TIGHTLY COUPLED to other code.
In the world of object oriented programming, a programmer develops an application by breaking down pieces of the application into entities called “classes”. Each class is responsible for taking care of a certain piece of functionality in the program.
One class could be solely responsible for handling the logging inside an application. Another class could be responsible for loading and saving data into a database. Yet another class could be responsible for handling any sort of e-mail communication needed in the application.
Breaking down an application into these individual classes is a great way to avoid creating a giant monolithic application. By breaking it down, it’s easier for a software programmer to understand each class component and how they interact with other class components, than trying to understand a giant application as a whole.
Unfortunately, object oriented programming introduces new problems as well. The problem of tight coupling, which was mentioned before.
In an object oriented application designed around classes, classes don’t exist as self isolated islands of code. Classes use other classes, in a big chain of interdependencies on each other.
The problem that arises from object oriented programming is when you need to make changes in the classes.
Because one class may need to rely on the functionality and services of many other classes, changing the definition or internal functionality of a class can cause unwanted rippling effects in other classes that depend on them.
This is what is meant by “tight coupling” between classes.
This where design patterns come into play. By understanding the major design patterns that have bubbled up into existence, there is a good chance there is a particular design pattern that a software programmer can implement in their specific software project. When successfully implemented, a design pattern ultimately makes the code easier to change. If the code is easy to change, it makes it easy to maintain as well.When successfully implemented, a design pattern ultimately makes the code easier to change. And if it's easy to change, it's easier to maintain as well. Click To Tweet
Yet even as design patterns help to reduce the negative impact of tightly coupled code, it has introduced new problems as well … namely, the abuse of using design patterns to the extreme.
There’s even a name for this overabundant abuse of using design patterns … “anti-patterns”.
The Anti-Pattern Problem
When I was first starting out in my professional software development career, I embraced every new fad in software design, every new programming language that came out, every new methodology.
Each new thing, whatever it was, boldly proclaimed it was the “ultimate silver bullet solution” for whatever problem in the field of software design field, it was supposed to solve.
But as I got older, gained more experience and paid my dues through the “school of hard knocks”, I believe I’ve learned at least ONE thing about software development … THERE IS NO SILVER BULLET SOLUTION.
The field of software engineering is still relatively young. It will continue to evolve long after I’m around. There will always be new technology stacks. New programming languages. New software design methodologies. Agile and Scrum, the latest flavor of the day of software design methodologies, will sooner or later, get replaced by something else.
As I’ve mentioned in many of my previous blog posts and articles, the only constant in software development is CHANGE.
I think if there was a universal design pattern or golden rule to follow in software development, it would probably be the famous golden rule:
KISS: Keep it Simple, Stupid
These days, I try to remain objective when it comes to any new technology stack, programming language or general trends in software architecture methodologies.
That’s not to say learning about new things isn’t important. You have to constantly stay marketable and relevant as a software developer.
But I eventually learned that every new line of code you write is a new potential thing which can go wrong.
The less code you write, the less time and effort you need to spend fixing, maintaining and/or refactoring that code.
Any code you write needs to be clean and simple, easy to read by other software developers and easy to change.
Easier said than done, I know … it takes a LIFETIME to master those two skills.
But I think a quote I read somewhere on the internet thoroughly convinced me of those two principles:
“Always code as if the guy who ends up maintaining your code will be a violent psychopath who knows where you live.”
Um, excuse me, I think I just heard a crazy sounding programmer upstairs in my house. Better call 5-0.
“Hello police? Yes, he’s calling me from INSIDE THE HOUSE!!!!”
This is an updated version of a previously published post.