Design Patterns in a nutshell
In this tutorial we will go over some design patterns and learn how to use them in real projects
We will go over the actual codes for all types of design patterns.
There are 3 categories of design patterns:
- Creational (Builder, Factory, Prototype, Singleton and others)
- Structural ()
- Behavioral (Iterator, Mediator, Observer, State and others)
Creational design patterns
Singleton.ts
class SingleTon {
private static instance: SingleTon;
private constructor() {}
public static getInstance(): SingleTon {
if (!SingleTon.instance) {
SingleTon.instance = new SingleTon();
}
return SingleTon.instance;
}
}
const s = SingleTon.getInstance();
// As objects in JS are passed by reference the below code
// can also be considered as Singleton
const singletonObj = {
test: 1,
};
Prototype.ts
// Prototype is just a fancy word for "clone"
// it basically permorms clone operation
const zombie = {
eatBrains() {
return 'yum 🧠';
},
};
const chad = Object.create(zombie, { name: { value: 'little chad' } });
console.log(chad.name, chad.eatBrains());
Structural design patterns
Proxy.ts
// This pattern is useful when you want to add an extra layer of control over access to an object.
// The proxy acts as an intermediary, controlling access to the real object.
const original = { name: 'Jeff' };
const reactive = new Proxy(original, {
get: (target, key) => {
console.log('Tracking: ', key);
return target[key];
},
set: (target, key, value) => {
console.log('Updating...');
return Reflect.set(target, key, value);
},
});
reactive.name;
reactive.name = 'Bob';
Behavioral design patterns
Iterator.ts
// Defines how items in a collection should be iterated
const arr = [1, 2, 3];
const obj = { name: 'Ism' };
for (const item of arr) {
console.log(item);
}
for (const prop in obj) {
console.log(prop, obj[prop]);
}
Mediator.ts
// Example: ExpressJS middleware
function logger(req, res, next) {
console.log('Request type is', req.method);
}
// @ts-ignore
app.use(logger);