JavaScript Design Patterns — Factory Pattern
Tags: webdev, programming, javascript, architecture
Published: 2021-01-30 21:29:14

**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 factory and observer patterns.

### Factory Pattern

The factory pattern is a design pattern that lets us create new objects and return them in a clean way.

For instance, we may want to return different kinds of things that are similar.

To make this easy for us, we can create a factory function that lets us return different kinds of objects with one factory function.

We can write:

```
class Fruit {
  //...
}

class Apple extends Fruit {
  //...
}

class Orange extends Fruit {
  //...
}

const fruitFactory = (type) => {
  if (type === 'apple') {
    return new Apple()
  } else if (type === 'orange') {
    return new Apple()
  }
}
```

We have the `fruitFactory` factory function that gets the `type` of an object as the argument and then return an object according to the type.

If we have `'apple'` as the value of `type` , we return an `Apple` instance.

And if we `type` set to `'orange'` , we return an `Orange` instance.

Now we can return different subclass instances of `Fruit` without writing them out explicitly.

If we make any changes to the class or add or remove them, then we can still use the same factory function and don’t break anything.

Some factory functions in JavaScript are in the standard library.

They include `String` for creating strings, `Number` for creating numbers from other entities, `Boolean` for convert variables to boolean, `Array` for creating arrays, and more.

Now we don’t have to worry about changes to the class structure messing up our code since we used a factory function to create our `Fruit` objects.

### Observer

The observer pattern is where we have multiple objects that listen to the one observable object.

This way, the observable object, which is also called the subject, can notify the objects that subscribed to the observable object with data that are emitted.

For instance, we can write:

```
const observable = {
  observers: {},
  subscribe(obj) {
    const id = Object.keys(this.observers).length + 1;
    this.observers[id] = obj;
    return id;
  },

  notify(data) {
    for (const o of Object.keys(this.observers)) {
      this.observers[o].listen(data);
    }
  }
}

const observer = {
  listen(data) {
    console.log(data);
  }
}
observable.subscribe(observer);
observable.notify({
  a: 1
});
```

We have the `observable` object that lets observer objects, which have a `listen` method to listen to data, to subscribe to notifications from the `observable` object.

When we can `observable.notify` with something as we did above, the `listen` method of the observer objects is run.

This way, the communication is all done by communicating via the `notify` method and nowhere else.

No implementations are exposed and therefore no tight coupling.

As long as the methods do the same thing, we shouldn’t have to worry about breaking the observer objects that subscribe to the `observable` .

We can also add an `unsubscribe` method to `observable` which uses the returned `id` from `subscribe` to remove an observer object from the `observers` object.

For instance, we can write:

```
const observable = {
  observers: {},
  subscribe(obj) {
    const id = Object.keys(this.observers).length + 1;
    this.observers[id] = obj;
    return id;
  },

  notify(data) {
    for (const o of Object.keys(this.observers)) {
      this.observers[o].listen(data);
    }
  },

  unsubscribe(id) {
    delete this.observers[id];
  }
}

const observer = {
  listen(data) {
    console.log(data);
  }
}
const subscriberId = observable.subscribe(observer);
observable.notify({
  a: 1
});

observable.unsubscribe(subscriberId);
```

We added an `unsubscribe` method so that we can remove the observer object from the `this.observers` list.

Once we unsubscribed, we won’t get notifications any more with the unsubscribed observer if we call `notify` again.

Examples of the observer pattern are used in many places.

Another good thing about the observer pattern is that we don’t communicate anything through the classes.

Loose coupling should always be preferred to tight coupling.

We only communicate through one channel in the example above so the observer pattern is as loose as coupling can get.

They include message queues and event handlers for GUI events like mouse clicks and key presses.

### Conclusion

We can use the observer pattern to decouple objects as much as possible.

All we do is receive events from one observable object that we want changes from.

The observable sends notifications to observer objects.

The factory pattern lets us create objects of similar types in one place by creating a factory function that lets us do that.