3 code examples of design patterns for your projects

Damián González

feb. 21º 2022

Code examples for design patterns

In this post, we are touring a new set of design patterns. Since we have already discussed the definition, history, and benefits of design patterns, today we will focus on the most well-known principles, such as SOLID.

First… what‘s a design pattern?

To start and just a refresher, I’ll give you a definition of what design patterns are so we are on the same page:

In software engineering, a design pattern is a generic, repeatable, and proven solution to a common problem in software creation, refactoring and design.

Although we can think of this as a description or a template that solves a problem, it’s important to know that design patterns are not libraries, cookbooks, or ready-to-deploy snippets. They represent a way of structuring a creative and logical process, not so much a single solution.

For this article, I’ve curated some of the most important patterns that I’ve seen in the Real World™. Anyway, if you still don’t know much about OOP and Javascript/Typescript principles, don’t worry. I’ll try to make this post accessible, fun, and easy😉

With this in mind, let’s dive into it!

1. The Singleton Pattern

These patterns, along with the SOLID, are often the most used.

Starting with the theoretical background, the singleton is used to have a single instance of a class in your entire application.

Does this ring any bell? If you’re a web developer working with popular libraries like React and Vue, you’ve probably used this pattern. And if you wonder at what point? Let me show you an example:

In React App, we tend to initialize a project with:
npx create-react-app <name-of-your-app>

As a result of the command mentioned above, we get the following structure:

name-of-your-app
├── README.md
├── node_modules
├── package.json
├── .gitignore
├── public
│ ├── favicon.ico
│ ├── index.html
│ └── manifest.json
└── src
├── App.css
├── App.js
├── App.test.js
├── index.css
├── index.js
├── logo.svg
└── serviceWorker.js
└── setupTests.js

At this point, we have created a React App. Now let’s focus on just one file: The App.js which is responsible for rendering our whole app.

By default, when we start our local server, we find something like this:

Local server
https://medium.com/media/7970fb5ebc3b1eb0c398eac8d59386a7/href

What if we need to extend this basic template to something more complex? Like adding a navigation bar, the main section with some call-to-action buttons? Or to make it visible throughout the app?

To achieve this, we can create each of the requested features like components, import them into the App.js, and instance them as wrappers of the <App> component. This way, we have a modular, decoupled app called one time only.

Following this solution, we have successfully applied the singleton pattern.

Singleton pattern
https://medium.com/media/afd9e41ac89fdd19e986d50177a02b4f/href

Of course, this was just a very simplified example to understand the essence of the singleton; there are best practices to apply when it comes to React.

2. The Factory Method pattern

The factory method is a creational design pattern that provides an interface for creating objects in a superclass. This pattern is a fusion between the single responsibility and open/closed principles.

This method is one of my favourites, as anyone who plays video games has probably experienced it. I’ll exemplify it with a famous and beloved game: Age of Empires.

Age of Empires (AoE) is a real-time strategy game that focuses on building cities, gathering resources, and raising armies to defeat an opponent.

In this game, the user can summon certain character types to join his army rank, for example, priests or villagers. The functions of the priests are to be able to convert enemy units and heal friendly ones. At the same time, villagers are the backbone of the economy of all civilizations; they perform key tasks like gathering resources and constructing buildings.

Age of empires
Defining our characters, their attributes, and skills.

With that said, let’s jump into the code to provide the factory method pattern:

https://medium.com/media/8a8314e67756bc481b89bccb180178ab/href

Firstly, we’ll create an interface (this solution is based on Typescript, as if we were using any other typed language such as C# or Java). With this on our codebase, we are ready to build our game characters factory:

https://medium.com/media/20667451c2035383cfdae614c5d1353c/href

This class takes care of building specific classes of game characters without ever calling class or any other code to know how those characters are created, what attributes they have, or any other specific logic. By doing it this way, we are honouring the single responsibility principle.

Also, by having this factory, we adhere to the open/close principle given that if we want to extend the catalogue of characters or delete them, we can do so by creating a new class or subclass for a new character, leaving the rest of the code unaffected.

Lastly, we have to create an instance of the game character factory on the main UI to let the player summon the characters we have just created:

https://medium.com/media/55ba46c38a273b614b6868e61bdccf65/href

This is quite an abstraction of what a real game will look like (in code), but the main idea is to prove the concept of this awesome pattern.

3. The observer pattern

In simple terms, the observer pattern is a behavioural design pattern that lets you define a subscription mechanism to alert or notify the observers or subscribers that something has happened.

The simplicity of this pattern is quite powerful and is spread everywhere.

Observer pattern

To understand this pattern, suppose we have just entered the cryptocurrency game and bought Dogecoin, intending to sell it, exchange it for another currency, or make a profit.

As developers, we can track the behavior of the currency more easily to make our decision. We can automate it by creating a simple bot that notifies us when to sell, when it reaches a limit we parametrize or when not to sell it.

Below we will create a relatively simple application that tracks and notify the Dogecoin price to know when to sell or not. Everything will run on the terminal for simplicity purposes:

https://medium.com/media/f3532c2e286e7d03003a5794e9a65a8f/href

This code intends to declare our observers that will be notified of the current price for our coin when it exceeds our defined highest price value and its lowest.

In the first lines, we define the properties or the values we are dealing with; then, we create a setter and getters to track those properties.

In this case, the setCurrentDogeCoinPrice setter is responsible for verifying if the values changed, are less, equal, or higher to trigger errors to let us know what happened with the coin price. Then, it will register all of these conditions considered in an array, in this case, the observers. Hence this is the core of the pattern:

The observer pattern is all about tracking for changes.

So far, we haven’t any value yet. For that, we will create the main app file, which will be responsible for programmatically providing all the necessary data for our observers to detonate messages.

https://medium.com/media/564c78a23c2d02ba2e71d2a54e961861/href

The following code has several purposes. The first one is in charge of connecting to the CoinMarketCap API and bringing the current price of the Dogecoin (the API might change in the future, this is for demo purposes). Then we have a simple function called sleep to regulate how often we will print the values in our terminal.

So now we have our main testing function testDogeCoinObsevers where we firstly instantiate our observers and then pass the necessary data to make it work.

We have passed into the observer an initial value of 400 USD. After that, we provide two functions that validate that initial value, which is recursively changing based on the coin price, setting the maximum price for the coin, and printing everything to the console. The rest will be handled by the observers that have registered themselves to the property.

The output of the code will look something like this.

Dodgecoin tracker
Our Dogecoin tracker in action shows the current price, when it’s close to the selling point, and when to sell. The price is simulated. Since it fluctuates linearly on the market, it can take too much or too little for the observer to change. It would be better to graph this data for a better UX.

Are you ready to implement design patterns in your projects?

I hope you can see the real power of design patterns in action at this point.

Obviously, besides the benefit of optimizing your code, arranging it in a more elegant and digestible way, and making it less prone to bugs. It catapults your career as Software Engineer or a Developer to the next level.

If you want to learn more about Design Patterns in a fun way, I’d suggest taking a look at the amazing book by Refactor Guru: Deep into Design Patterns. Also, if you are curious about what we do at Nowports and have some insight from our experts, take a look at our blog.


3 code examples of design patterns for your projects was originally published in Nowports Tech on Medium, where people are continuing the conversation by highlighting and responding to this story.