I am excited to be starting a new series where we will dive a bit into some of the trending design patterns for front-end developers.

Design patterns are a crucial part of software development, offering tried and tested solutions to common problems that can be used to improve collaboration when working with many people on the same project.

In this first article, we will be exploring the Singleton pattern that ensures a class has only one instance and provides a global point of access to it. Stay tuned for more articles exploring different design patterns in this series.

Singleton Pattern

The Singleton Pattern is a type of design pattern that restricts the creation of a class to only one instance. This is useful in scenarios where a single point of control or coordination is required. In other words, it ensures that a class has only one instance, and provides a global point of access to it.

This pattern is often used for configuration data, caches, or connection pools or logging where it's more efficient to have one instance running that can be used by other processes in an application. It also can be useful when you need to maintain state, initialize fields or manage a queue of calls and callbacks.

For instance, if an application has a dropdown list of items that is accessed from various places, a Singleton can manage this shared resource. This ensures that if the list is modified in one place, the changes are reflected across the entire application.

If you need this information to be shared across multiple instances of your application (like different devices), you can use the Real-time Data Engine from SuperViz. Designed with developers in mind, it provides an effortlessly seamless integration into your projects, enabling you to implement design patterns such as the Publisher/Subscriber Pattern. Our engine ensures efficient and real-time updates, transforming your application's responsiveness and overall user experience.

Singleton Example

Here's a basic example of how this dropdown list might be implemented in JavaScript:

1let dropdownListItems;
2class DropdownList {
3 constructor(items = []) {
4 if (dropdownListItems) {
5 return dropdownListItems;
6 }
7
8 dropdownListItems = items;
9 }
10
11 addItem(item) {
12 dropdownListItems.push(item);
13 }
14
15 removeItem(item) {
16 dropdownListItems = dropdownListItems.filter(i => i !== item);
17 }
18}
19
20const dropdownList = new DropdownList();
21export default dropdownList;

This JavaScript code defines a class DropdownList and an instance of it.

  1. dropdownListItems is a variable that is initially undefined.
  2. The DropdownList class is defined with a constructor that accepts an array of items as an argument, defaulting to an empty array if no argument is provided.
  3. In the constructor, if dropdownListItems is already defined, it returns the one defined. If dropdownListItems is not defined, it assigns the items argument to dropdownListItems.
  4. The DropdownList class has two methods: addItem and removeItem.
    • addItem method: This method accepts an item as an argument and pushes it to the dropdownListItems array.
    • removeItem method: This method accepts an item as an argument and removes it from the dropdownListItems array. It does this by reassigning dropdownListItems to a new array that filters out the item to be removed.
  5. An instance of DropdownList is created with no arguments, so it will be initialized with an empty array. This instance is stored in the dropdownList constant.

Singleton Pattern with ES2016

The code above shows how to implement the singleton with the ES2015, I choose to show you this way before to make it simpler to understand what the singleton is about.

However, with ES2016 introduced the static keyword, which can be used to create a static instance property on the class. This static instance property can be used to hold the single instance of the class.

1class DropdownList {
2 static dropdownListItems = [];
3
4 constructor(items = []) {
5 if (DropdownList.dropdownListItems.length) {
6 return DropdownList.dropdownListItems;
7 }
8 DropdownList.dropdownListItems = items;
9 }
10
11 addItem(item) {
12 DropdownList.dropdownListItems.push(item);
13 }
14
15 removeItem(item) {
16 DropdownList.dropdownListItems = DropdownList.dropdownListItems.filter(i => i !== item);
17 }
18}
19
20const dropdownList = new DropdownList();
21
22export default dropdownList;

In this ES2016 version, the instance is a static property on the class itself, rather than a separate variable. This makes it clear that the instance is associated with the class, not just some random variable on top.

The instance is created when the module is loaded, and the same instance is returned every time the class is imported. This also means that we don’t need the Object.freeze(player); anymore.

Stay tuned for more posts in this series where we'll continue to explore different design patterns. Don't forget to follow and like if you found this useful, and feel free to leave any questions you have in the comments section.