Sponsor: Do you build complex software systems? See how NServiceBus makes it easier to design, build, and manage software systems that use message queues to achieve loose coupling. Get started for free.
Should you care about design patterns? There are books devoted to them; heck, even I post videos about specific design patterns. But do they matter? If you’re new to design, it can be overwhelming and cause a lot of unneeded complexity. I will cover how I think of design patterns or how I don’t think of design patterns.
Check out my YouTube channel, where I post all kinds of content accompanying my posts, including this video showing everything in this post.
In my own personal experience, and witnessing the same occur to other developers in their careers, is a mid-career explosion of complexity. Design Patterns play a big role in this explosion of complexity.
Early on in a developer’s career, they are often righting pretty simple code. While that code may be highly coupled and flawed, they generally write “simple code.”
Now we can argue what “simple code” means, but speaking for myself, it was straightforward without any magic. You aren’t writing “smart” or “clever” code. What you see is what you get. There was little indirection.
As you gain more experience and read or watch various tutorials/courses/books, you start seeing every problem as a means to solve by patterns.
There is a similar case to be made for doing the same thing with the latest technology, library, framework, or platform. You learn something new and immediately want to apply it. Unfortunately, this often leads to using it aimlessly. Meaning you have a hammer, so everything starts looking like a nail.
Now you might be thinking, “really, people are just applying patterns for no good reason?”. Yes, this is more common than you think. It can also be because you’re applying patterns because you think you have the problem it solves. More on that later.
Hopefully, you feel enough pain in this phase of your career where you can realize you aren’t solving problems but rather creating unneeded complexity. On the bright side, you’ll better understand various patterns and the problems they solve, as you’ve used them for the right and wrong reasons.
On the other side of the complexity, the nightmare phase is back to the simplicity that resembles the naive code you’ve written at the beginning of your career.
That’s not to say you’re writing beginner code, but it’s focused, trivial, with no magic, and less useless indirection. It’s direct and to the point. As someone commented on the YouTube video:
It took me four years to paint like Raphael, but a lifetime to paint like a child.Pablo Picasso
A key to patterns is communication. Named patterns are a way to communicate between developers about solutions and implementations for various problems. For example, one developer is explaining a problem they are having with another developer. The other developer says that the problem could be solved by [Insert Named Pattern]. If both developers understand the named pattern, they don’t have to get lost in the deep implementation details of that pattern. They already understand it. It’s a communication tool.
According to many comments on various videos I’ve done on YouTube, it’s common for people to apply a pattern without even realizing it’s a named pattern. I have done this countless times over my career. You’re faced with a problem and come up with a solution that turns out to be a named pattern! Once you realize this, great! You understand both the problem the pattern truly solves and how to implement it.
Knowing the names of patterns and the problems they solve is great for communication.
Avoiding the Problem
Earlier I mentioned that you could apply patterns for problems you think you have. However, it’s often helpful to examine why you have the problem. Meaning one solution is to avoid the problem in the first place.
To illustrate this, I’m going to use the example of the Repository Pattern. Now you could take this example more abstractly and apply it to other patterns that add indirection.
There are different definitions of the repository pattern, but for this example, I’ll say it’s used to encapsulate data access logic.
Mixing data access logic with other concerns sounds like a terrible idea. However, there is an underlying issue that’s not talked about. Coupling.
With the repository, you’re coupling to it rather than likely using a native database provider directly. The purpose of abstractions is to simplify the interface for your purpose. The repository pattern can do this for us. Great. However, you still have the same degree of coupling from your application code using the repository.
If you have hundreds (or thousands) of usages of the repository in your application code, you have a high degree of coupling to your repository. If you make any breaking changes to your repository, you’re faced with changing all calling code that breaks.
Another solution is to limit coupling.
In many situations, it’s not that you need all the data or implementation of the repository. Often you only need a subset. The repository might not be ideal in every situation. I talked about this in my post Should you use the Repository Pattern? With CQRS, Yes and No!
Using your repository abstraction might be helpful in one situation and not ideal in another. You may decide a subset of features is grouped together, use the same related data, and use a repository. Another subgroup of features might choose to access data differently because of its use case.
The problem isn’t that you need to encapsulate data access; the problem is you have a high degree of coupling of calling code that needs data access. One solution is to encapsulate data access with a repository. Another is to limit coupling, so the need for encapsulating data access is less of a concern or decided per situation.
Should you care about design patterns? Yes, absolutely. Understanding the names of design patterns and the problems they solve is helpful. It’s a great way to communicate with other developers when discussing problems and solutions. However, don’t apply a pattern unless you truly have the problem it solves. Do you have the problem it solves? Or should you look at ways to eliminate the problem.
Developer-level members of my YouTube channel or Patreon get access to a private Discord server to chat with other developers about Software Architecture and Design and access to source code for any working demo application I post on my blog or YouTube. Check out my Patreon or YouTube Membership for more info.