I’m excited to be starting a new series where we’ll 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’ll 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:
let dropdownListItems;
class DropdownList {
constructor(items = []) {
if (dropdownListItems) {
return dropdownListItems;
}
dropdownListItems = items;
}
addItem(item) {
dropdownListItems.push(item);
}
removeItem(item) {
dropdownListItems = dropdownListItems.filter(i => i !== item);
}
}
const dropdownList = new DropdownList();
export default dropdownList;
This JavaScript code defines a class DropdownList
and an instance of it.
-
dropdownListItems
is a variable that is initiallyundefined
. - 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. - In the constructor, if
dropdownListItems
is already defined, it returns the one defined. IfdropdownListItems
is not defined, it assigns theitems
argument todropdownListItems
. - The
DropdownList
class has two methods:addItem
andremoveItem
.-
addItem
method: This method accepts an item as an argument and pushes it to thedropdownListItems
array. -
removeItem
method: This method accepts an item as an argument and removes it from thedropdownListItems
array. It does this by reassigningdropdownListItems
to a new array that filters out the item to be removed.
-
- An instance of
DropdownList
is created with no arguments, so it will be initialized with an empty array. This instance is stored in thedropdownList
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.
class DropdownList {
static dropdownListItems = [];
constructor(items = []) {
if (DropdownList.dropdownListItems.length) {
return DropdownList.dropdownListItems;
}
DropdownList.dropdownListItems = items;
}
addItem(item) {
DropdownList.dropdownListItems.push(item);
}
removeItem(item) {
DropdownList.dropdownListItems = DropdownList.dropdownListItems.filter(i => i !== item);
}
}
const dropdownList = new DropdownList();
export 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.
Top comments (6)
Great explanation of singleton patterns, I'm really liking your series on design patterns too.
One thing I found interesting is your use of
static
on your es16 class.Whilst your example here does work I would argue that
dropDownListItems
doesn't need to be a static property. Static properties and methods are usually used to access to properties on the class prototype. So you don't need to use thenew
keyword to instantiate the class in order to access the property. But, since you're using the singleton pattern, you always have an instantiated class so the static method is superfluous.You could achieve the same thing with just the following:
By removing the static method, it removes confusion about if this class prototype should be accessible.
Otherwise, really nice write up and great explanation of singleton patterns
@stretch0 I think your modification of the code does not follow the Singleton pattern since whenever we'll instantiate the
DropdownList
class, it will create a newdropdownListItems
Why there is a value returned from the constructor?
Since DropdownList is a singleton class, there should only be a single instance of it. By returning from within the constructor, we are making sure that we get the same dropdownListItems whenever we try to instantiate the class.
But
dropdownList2.addItem('test');
won't work!thanks pro