JavaScript Design Patterns — Chain of Responsibility, Singleton, and Flyweight Patterns
Tags: webdev, programming, javascript, architecture
Published: 2021-01-30 21:29:31

**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.