I wrote a few articles about design patterns. A few examples are the Repository Pattern (or the generic version) and the Strategy Pattern. Both are very effective when writing software. But I have also mentioned SOLID, which is a collection of design principles. But what is the difference between design patterns and design principles? When do we talk about a design pattern and when about a design principle?
Design patterns and principles are here to help us make better code. Where one focuses more on the architecture and guidelines, the other focuses more on solutions in code. It’s important to know that we — developers — have some sort of guidelines and solutions as you go. But remember we are working with software: Expect the unexpected and not all environments are the same.
In my years as a developer, I have come across a lot of principles and patterns. Some are thought of by a team member and it works for that solution and some are defined by great minds, still maintained, and are used to this day. This article is about the latter.
Both have different definition that already shows the big difference between them. A design pattern is a solution to a particular problem. Most definitions can be shown in code. Because it can be translated to code, the solution is usually reusable and helps to solve recurring design issues.
A design principle is a guide that explains certain solutions or guidelines to developers, making it easier to solve problems that might occur in code. These guidelines are here to help us prevent problems. Design problems help us create robust, maintainable, and flexible software. A design principle is not code, only theory.
One of the most well-known design patterns is the Singleton Pattern. This pattern states and shows that a class should be initiated only once and this instance should be used throughout the application’s lifecycle. This pattern can be used in all programming languages that use classes and initiates classes.
Another example is the Strategy Pattern. This pattern is a behavioral pattern that enables dynamic selection and interchangeability of algorithms or strategies at runtime. You can simplify complex if-statements or make dynamic choices at runtime.
Other examples are the Observer pattern and the Factory pattern. But there are way more. You can divide them into 3 categories: Creational design, structural design, and behavioral design. The image below gives you a good idea of which patterns belongs in what category.
It is (almost) impossible to know and learn them all. My advice: Learn the basic idea of them, know when you can use them, and figure out how they work when you are in a situation where you might think “Oh, I know a pattern for that!”
If you look at the design principles, we see other names coming up. Names like SOLID, DRY, KISS, and other funny-looking abbreviations.
DRY stands for Don’t Repeat Yourself, which states that you should not write duplicate code. Duplicate code can cause a lot of problems when you have to change something. Avoid issues and write your code once and reuse it in other parts of your application.
KISS stands for Keep It Simple Stupid, although the last ‘s’ is removed in this day and age. This one states that code should be simple and understandable for others. The more complex you make it, the harder it becomes to understand.
SOLID is a collection of different principles: Single Responsibility, Open-Closed, Liskov Substitution, Interface Segregation, and Dependency Inversion, I could give examples for all of them, but then it would be a lot of reading for you (and writing for me). If you follow Wikipedia on SOLID, you will get a lot of information.
The moment you use a principle or pattern is different too. There is no one-size-fits-all solution and you might not use them at all. It goes without saying that design patterns are used during coding since they give solutions to certain code issues. Patterns can be added or removed along the way.
While creating software, your views might change (or those of a manager). This makes you decide differently and you might want to add or remove a pattern. This is okay. For example, a simple if-statement suddenly becomes this monster of if-elseif-elseif-elseif-elseif-etc. Then maybe it’s time to implement the strategy pattern.
Design principles are usually applied in the early stages of development. They are mostly about architectural design and planning. But also high-level designs. These are things you can’t change when you are halfway through coding your application.
The Single Responsibility Principle (SRP) is pretty important. If you lose control of this one and classes and methods get multiple responsibilities, you might end up refactoring your code and breaking a lot of methods because the responsibility might be scattered across multiple methods and classes.
Design patterns are proven solutions that can help solve reoccurring problems. Design principles are guidelines that can help you give structure and architecture to your software. That’s it, that’s all.
You don’t need to use all patterns and principles that exist. In fact, using all SOLID principles in a single software application is nearly impossible. I managed it once, and that was a fairly small project.
It’s a good practice to look at the differences between design principles and design patterns and know when to use which one. Again, it is almost impossible to know all patterns and principles by heart, but know the names and the basic idea behind them.