GoF Creational Patterns

Definition

Creational Design Patterns focus on handling object creation mechanisms where objects are created in a manner suitable for the situation we're working in. The basic approach to object creation might otherwise lead to added complexity in a project whilst these patterns aim to solve this problem by controlling the creation process.

  • Constructor

  • Factory

  • Abstract Factory

  • Prototype

  • Singleton

  • Builder

Constructor

Constructor - is a special method used to initialize a newly created object once the memory has been allocated for it.

Constructors are language construct in many OO-programming languages. However, in JS, you can create an object simply by defining properties on-the-fly. Constructor pattern gives us a way of defining properties and methods to a specific type of object to give it a consistent behavior.

Instead of classes, we can use also special constructor functions that work with objects. By simply prefixing a call to a constructor function with the keyword "new", we can tell JavaScript we would like the function to behave like a constructor and instantiate a new object with the members defined by that function. Inside a constructor, the keyword this references the new object that's being created.

Use: To create objects having some consistency in behavior among them.

Example:

class Fruit {
  constructor(name, taste) {
    this.name = name;
    this.taste = taste;
  }
}

const apple = new Fruit('apple', 'sweet');
const orange = new Fruit('orange', 'tangy');

Example in FE world: JS has constructors natively

Factory Method

Factory method makes an instance of several derived classes based on interfaced data or events.

Example:

class Bmw {
  constructor(model, price, maxSpeed) {
    this.model = model;
    this.price = price;
    this.maxSpeed = maxSpeed;
  }
}

class BmwFactory {
  static create(type) {
    if (type === 'X5')
      return new Bmw(type, 108000, 300);
    if (type === 'X6')
      return new Bmw(type, 111000, 320);
  }
}

Abstract Factory

Abstract Factory creates an instance of several families of classes without detailing concrete classes.

Example:

function droidProducer(kind) {
  if (kind === 'battle') return battleDroidFactory;
  return pilotDroidFactory;
}

function battleDroidFactory() {
  return new B1();
}

function pilotDroidFactory() {
  return new Rx24();
}

class B1 {
  info() {
    return "B1, Battle Droid";
  }
}

class Rx24 {
  info() {
    return "Rx24, Pilot Droid";
  }
}

Builder

Builder separates object construction from its representation, always creates the same type of object.

Example:

class Request {
  constructor() {
    this.url = '';
    this.method = '';
    this.payload = {};
  }
}

class RequestBuilder {
  constructor() {
    this.request = new Request();
  }

  forUrl(url) {
    this.request.url = url;
    return this;
  }

  useMethod(method) {
    this.request.method = method;
    return this;
  }

  payload(payload) {
    this.request.payload = payload;
    return this;
  }

  build() {
    return this.request;
  }
}

Prototype

Prototype - a fully initialized instance used for copying or cloning.

The Prototype pattern is one that creates objects based on a template of an existing object through cloning.

We can think of the prototype pattern as being based on prototypal inheritance where we create objects which act as prototypes for other objects. The prototype object itself is effectively used as a blueprint for each object the constructor creates. If the prototype of the constructor function used contains some property, then each object created by that same constructor will also have this same property.

One of the benefits of using the prototype pattern is that we're working with the prototypal strengths JavaScript has to offer natively rather than attempting to imitate features of other languages.

Not only is the pattern an easy way to implement inheritance, but it can also come with a performance boost as well: when defining a function in an object, they're all created by reference (so all child objects point to the same function) instead of creating their own individual copies.

Example:

class Sheep {

  constructor(name, weight) {
    this.name = name;
    this.weight = weight;
  }

  clone() {
    return new Sheep(this.name, this.weight);
  }
}

Example in FE world: JS implements prototyping inheritance out of the box

Singleton

Singleton - a class with only a single instance with global access points.

The Singleton pattern is thus known because it restricts instantiation of a class to a single object. Classically, the Singleton pattern can be implemented by creating a class with a method that creates a new instance of the class if one doesn't exist. In the event of an instance already existing, it simply returns a reference to that object.

Example:

class Person {
  constructor() {
    if (typeof Person.instance === 'object') {
      return Person.instance;
    }
    Person.instance = this;
    return this;
  }
}

Examples from FE world: es6 modules are singletons, Redux state is a singleton.

Last updated

Was this helpful?