Ismoil Shokirov's image

Ismoil Shokirov's blog

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);

Find all examples in my github repo