CodeBlanks Logo Icon CodeBlanks

Summary - Design patterns

JavaScript course · Expert · Lesson 6/63

Build an event-emitter library using the Observer and Factory patterns.

Summary - Design patterns

In this group we covered four common design patterns:

  • Singleton: a single instance guarantee.
  • Factory: separates object creation.
  • Observer: event emission and subscription.
  • Module: private state with an IIFE.

In the final task we will combine the Observer and Factory patterns to build a small event-emitter library. We will use the EventEmitter class and the createChannel factory together.

Exercise EventEmitter class

Declare an EventEmitter class. Its on(event, callback) method adds callback to the subscriber array for that event. Its emit(event, data) method calls every subscribed callback with data.

Show example solution
Start with class EventEmitter, in on(event, callback) call this.listeners[event].push(callback), in emit(event, data) call subscribers with cb(data).
Example solution:
class EventEmitter {
  constructor() {
    this.listeners = {};
  }
  on(event, callback) {
    if (!this.listeners[event]) {
      this.listeners[event] = [];
    }
    this.listeners[event].push(callback);
  }
  emit(event, data) {
    if (this.listeners[event]) {
      for (const cb of this.listeners[event]) {
        cb(data);
      }
    }
  }
}

Event-emitter library

You have a two-step mini task. First, write the EventEmitter class: on(event, callback) adds a subscriber, emit(event, data) calls every subscriber.

Then add a createChannel(name) factory function. Each call produces a new EventEmitter instance and wraps it with subscribe and publish methods.

This combines the Observer (emission) and Factory (creation) patterns.

Exercise createChannel factory

Write a createChannel(name) factory function. Inside it, create a new EventEmitter instance. The returned object should have subscribe(callback) and publish(data) methods. The subscribe method should call emitter.on; the publish method should call emitter.emit.

Show example solution
Start with function createChannel(name), create const emitter = new EventEmitter();, end with return { subscribe(callback) { emitter.on('message', callback); }, publish(data) { emitter.emit('message', data); } }.
Example solution:
function createChannel(name) {
  const emitter = new EventEmitter();
  return {
    name: name,
    subscribe(callback) {
      emitter.on('message', callback);
    },
    publish(data) {
      emitter.emit('message', data);
    }
  };
}

Test yourself

  1. What is the role of the Factory pattern in an event-emitter library?

    • Hide the subscriber list
    • Rename the class
    • Produce new channel instances
    • Sort events
    Show answer

    Produce new channel instances — Correct! The createChannel factory produces a new channel per call.

  2. Match the patterns

    Singleton
    Single instance
    Factory
    Object creation
    Observer
    Event emission
    Module
    Private state

All lessons in Expert