Check out my books on Amazon at https://www.amazon.com/John-Au-Yeung/e/B08FT5NT62
Subscribe to my email list now at http://jauyeung.net/subscribe/
Design patterns are the basis of any good software. JavaScript programs are no exception.
In this article, we’ll look at the chain of responsibility, singleton, and flyweight patterns.
Chain of Responsibility Pattern
The chain of responsibility is similar to the observer pattern, except that it sends the notification to one object, and then that object sends the notification to another object, and so on.
In the observer pattern, the notification is sent to all the observers at the same time.
For instance, if we send something to one object and then that object picks that up and does something with and send that to another and so on, then that implements the chain of responsibility patterns.
We can implement that as follows:
const backend = {
receive(data) {
// do something with data
}
}
const middleLayer = {
notify(data) {
backend.receive(data);
}
}
const frontEnd = {
notify(data) {
middleLayer.notify(data);
}
}
In the code above, we have the frontEnd
, which calls the notify
method of the middleLayer
object, which in turn called the backend
‘s receive
method.
This way, we can pass data between them with one method seamlessly.
As long as we don’t expose any other methods that do communication between both objects, we have a clean way of sending data between frontEnd
and middleLayer
and backEnd
.
Singleton
The singleton pattern is where we only instantiate one instance of an object.
In JavaScript, we can create objects with one instance by creating an object literal.
We can create one by writing:
const obj = {
foo: 1,
bar: 'baz'
}
An object literal is just sets of key-value pairs, where the value can also be other objects.
If we use classes, we can also write:
class Foo {
constructor() {
if (!Foo.instance) {
Foo.instance = {
foo: 1,
bar: 2
}
}
return Foo.instance;
}
}
We assigned the created instance to the instance
property of Foo
.
Then when we create the constructor, we check the instance
property to see if anything’s created for it.
If there’s nothing assigned to it then we assign an object to it.
Then we return Foo.instance
so that we get the instance.
Now if we create 2 instances of Foo
:
const foo = new Foo();
const bar = new Foo();
Then we can see if they’re the same instance by writing:
console.log(foo === bar);
We should get true
since they both reference the same instance.
Singletons are handy for creating objects that are used by multiple pieces of code to store data in a central place.
If we don’t want conflicts in how data is accessed, then we can create a singleton instance of a class or an object literal to make sure that there are no issues with conflicts.
Flyweight Pattern
The flyweight pattern is where we restrict object creation,
We create a set of small objects that each consume a smaller amount of resources.
These objects sit behind a flyweight object, which is used to interact with these objects,
Those objects also interact with our code.
This way, we get the benefits of a big object, while we interact with smaller objects that are more manageable.
For instance, we can implement it as follows:
class Student {
//..
}
const studentIdentity = {
getIdentity(){
const student = new Student();
//..
return {
//...
}
}
}
const studentScore = {
getScore(){
const student = new Student();
//..
return {
//...
}
}
}
We have a Student
class that represents a student’s data.
Then in the studentIdentity
and studentScore
objects, we have methods to get his or her identity or score respectively.
This way, we don’t have to put all the methods into the Student
class.
Instead, we have methods outside of it that are smaller that we can use to deal with specific kinds of student data.
Conclusion
We can use the singleton pattern to create one-off objects.
We can either create class instances with only one instance or with object literals.
The flyweight pattern is where we create smaller objects to deal with big objects, thereby reducing complexity.
The chain of responsibility pattern lets us send data from one object to another in a series fashion.