JavaScript
Summary - Design patterns
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
-
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.
-
Match the patterns
- Singleton
- Single instance
- Factory
- Object creation
- Observer
- Event emission
- Module
- Private state
Next lesson: Performance measurement