Before I get into this specific design pattern, I’d like to talk a bit about what a design pattern is and why it is important as a programmer. Let’s get started!
When I first began learning to code, I never really thought about things such as design patterns and algorithms. I just focused on learning the syntax and solving simple coding problems, overall I was just excited to be learning a new skill! But… as I progressed, I soon realized that design patterns and solving algorithms are probably two of the most important things a professional software engineer needs to know! In a software engineering job, you aren’t just building websites for fun, you’re building massive web applications with complex systems that need to run perfectly if you want your users to have a great experience.
When building large scale applications, it is important to know some design patterns. Implementing design patterns will make your code more reusable, scalable, flexible, and overall cleaner and more powerful!
Design patterns aren’t just a couple functions you can start using when coding, it’s a repeatable solution to common problems you will encounter in software design. There are many design patterns, such as the singleton, iterator, facade, constructor, adapter, prototype, observer, and many more. Learning as many design patterns as you can and implementing them in projects will make you a more experienced and well-rounded software engineer. Let’s get started with our first design pattern.
Singleton Design Pattern
The Singleton Design pattern is implemented to only allow one instantiation of a class object. The typical goal of this pattern is to manage the global state of your application. A few real world examples could be using a singleton as the source of config settings for a web app, on the client-side for initiating an API, and to store data in memory on the client-side. Another important thing to note about a singleton is that it should be immutable by any outside code, and you should be certain that no more than one can be instantiated.
When the above code is interpreted, UserStore is set to the result of the immediately invoked function. This function returns an object with two functions, but does not allow direct access to the data stored.
We can test that the design works:
As you can see, we successfully created an instance of a user and stored it inside of our singleton, we were also able to reference the created user by using the get() method we created.
However, this does not solve the problem of immutability to outside code. The add() and get() functions can be changed, and the entire UserStore could be changed as well. That’s a problem!
By leveraging ES6, we can solve this problem. The const variable declaration comes in handy in making sure that once a variable is declared it can no longer be changed:
This example has a few improvements:
- readability — ES6 syntax has both readable and clean code
- use of const — This prevents our UserStore from being reassigned in the future
- use of Object.freeze() — This prevents the objects methods from being changed, and also prevents new methods from being added to it.
ES6 also allows the use of classes, which can come in handy when wanting to take advantage of traditional Object-Oriented Inheritance:
Because the example we’re using is so small, we really don’t see any advantages to using the ES6 classes, but it is always good to see what your options are.
Often times, using the class syntax is great when you’re frontend is also interacting with a backend. This allows you to use a lot of the same design patterns on both ends and can increase your teams efficiency.
To ensure that your singleton is solid and can in no way be overridden by any outside sources, we can check to be sure that there is only one instance before allowing an instance to be created:
Adding these few extra steps can completely ensure that our class will check if an instance has already been created. If one is already created then a new one will not be created, otherwise, an instance of the class will be created.
Of course, there are pros and cons to using this pattern, and there will always be arguments as to which method of the singleton is better and which is worse. My advice would be to keep an open mind and focus on the project at hand. This way, you can concentrate on which method will be most beneficial in your specific scenario.
Thanks so much for reading, and I hope you were able to learn something from this article. I plan to continue growing as a developer and perfecting my skills in using design patterns. I hope you do the same, Happy coding!