Reader small image

You're reading from  TypeScript Design Patterns

Product typeBook
Published inAug 2016
Reading LevelIntermediate
PublisherPackt
ISBN-139781785280832
Edition1st Edition
Languages
Tools
Right arrow
Author (1)
Vilic Vane
Vilic Vane
author image
Vilic Vane

Vilic Vane is a JavaScript engineer with over 8 years of experience in web development. He started following the TypeScript project since it went public, and hes also a contributor of the project. He is now working at Ruff, a startup company building an IoT platform that runs JavaScript on embedded devices.
Read more about Vilic Vane

Right arrow

Chapter 3. Creational Design Patterns

Creational design patterns in object-oriented programming are design patterns that are to be applied during the instantiation of objects. In this chapter, we'll be talking about patterns in this category.

Consider we are building a rocket, which has payload and one or more stages:

class Payload { 
  weight: number; 
} 
 
class Engine { 
  thrust: number; 
} 
 
class Stage { 
  engines: Engine[]; 
} 

In old-fashioned JavaScript, there are two major approaches to building such a rocket:

  • Constructor with new operator

  • Factory function

For the first approach, things could be like this:

function Rocket() { 
  this.payload = { 
    name: 'cargo ship' 
  }; 
   
  this.stages = [ 
    { 
      engines: [ 
        // ... 
      ] 
    } 
  ]; 
} 
 
var rocket = new Rocket(); 

And for the second approach, it could be like this:

function buildRocket...

Factory method


Under some scenarios, a class cannot predict exactly what objects it will create, or its subclasses may want to create more specified versions of these objects. Then, the Factory Method Pattern can be applied.

The following picture shows the possible structure of the Factory Method Pattern applied to creating rockets:

A factory method is a method of a factory that builds objects. Take building rockets as an example; a factory method could be a method that builds either the entire rocket or a single component. One factory method might rely on other factory methods to build its target object. For example, if we have a createRocket method under the Rocket class, it would probably call factory methods like createStages and createPayload to get the necessary components.

The Factory Method Pattern provides some flexibility upon reasonable complexity. It allows extendable usage by implementing (or overriding) specific factory methods. Taking createStages method, for example, we can...

Abstract Factory


The Abstract Factory Pattern usually defines the interfaces of a collection of factory methods, without specifying concrete products. This allows an entire factory to be replaceable, in order to produce different products following the same production outline:

The details of the products (components) are omitted from the diagram, but do notice that these products belong to two parallel families: ExperimentalRocket and FreightRocket.

Different from the Factory Method Pattern, the Abstract Factory Pattern extracts another part called client that take cares of shaping the outline of the building process. This makes the factory part focused more on producing each component.

Participants

The participants of a typical Abstract Factory Pattern implementation include the following:

  • Abstract factory: RocketFactory

Defines the industrial standards of a factory which provide interfaces for manufacturing components or complex products.

  • Concrete factory: ExperimentalRocketFactory, FreightRocketFactory...

Builder


While Factory Patterns expose the internal components (such as the payload and stages of a rocket), the Builder Pattern encapsulates them by exposing only the building steps and provides the final products directly. At the same time, the Builder Pattern also encapsulates the internal structures of a product. This makes it possible for a more flexible abstraction and implementation of building complex objects.

The Builder Pattern also introduces a new role called director, as shown in the following diagram. It is quite like the client in the Abstract Factory Pattern, although it cares only about build steps or pipelines:

Now the only constraint from RocketBuilder that applies to a product of its subclass is the overall shape of a Rocket. This might not bring a lot of benefits with the Rocket interface we previously defined, which exposes some details of the rocket that the clients (by clients I mean those who want to send their satellites or other kinds of payload to space) may not...

Prototype


As JavaScript is a prototype-based programming language, you might be using prototype related patterns all the time without knowing it.

We've talked about an example in the Abstract Factory Pattern, and part of the code is like this:

class FreightRocketFactory 
implements RocketFactory<FreightRocket> { 
  createRocket(): FreightRocket { 
    return new FreightRocket(); 
  } 
} 

Sometimes we may need to add a subclass just for changing the class name while performing the same new operation. Instances of a single class usually share the same methods and properties, so we can clone one existing instance for new instances to be created. That is the concept of a prototype.

But in JavaScript, with the prototype concept built-in, new Constructor() does basically what a clone method would do. So actually a constructor can play the role of a concrete factory in some way:

interface Constructor<T> { 
  new (): T; 
} 
 
function createFancyObject...

Singleton


There are scenarios in which only one instance of the specific class should ever exist, and that leads to Singleton Pattern.

Basic implementations

The simplest singleton in JavaScript is an object literal; it provides a quick and cheap way to create a unique object:

const singleton = { 
  foo(): void { 
    console.log('bar'); 
  } 
}; 

But sometimes we might want private variables:

const singleton = (() => { 
  let bar = 'bar'; 
   
  return { 
    foo(): void { 
      console.log(bar); 
    } 
  }; 
})(); 

Or we want to take the advantage of an anonymous constructor function or class expression in ES6:

const singleton = new class { 
  private _bar = 'bar'; 
   
  foo(): void { 
    console.log(this._bar); 
  } 
} (); 

Note

Remember that the private modifier only has an effect at compile time, and simply disappears after being compiled to JavaScript (although of course its accessibility...

Summary


In this chapter, we've talked about several important creational design patterns including the Factory Method, Abstract Factory, Builder, Prototype, and Singleton.

Starting with the Factory Method Pattern, which provides flexibility with limited complexity, we also explored the Abstract Factory Pattern, the Builder Pattern and the Prototype Pattern, which share similar levels of abstraction but focus on different aspects. These patterns have more flexibility than the Factory Method Pattern, but are more complex at the same time. With the knowledge of the idea behind each of the patterns, we should be able to choose and apply a pattern accordingly.

While comparing the differences, we also found many things in common between different creational patterns. These patterns are unlikely to be isolated from others and some of them can even collaborate with or complete each other.

In the next chapter, we'll continue to discuss structural patterns that help to form large objects with complex...

lock icon
The rest of the chapter is locked
You have been reading a chapter from
TypeScript Design Patterns
Published in: Aug 2016Publisher: PacktISBN-13: 9781785280832
Register for a free Packt account to unlock a world of extra content!
A free Packt account unlocks extra newsletters, articles, discounted offers, and much more. Start advancing your knowledge today.
undefined
Unlock this book and the full library FREE for 7 days
Get unlimited access to 7000+ expert-authored eBooks and videos courses covering every tech area you can think of
Renews at €14.99/month. Cancel anytime

Author (1)

author image
Vilic Vane

Vilic Vane is a JavaScript engineer with over 8 years of experience in web development. He started following the TypeScript project since it went public, and hes also a contributor of the project. He is now working at Ruff, a startup company building an IoT platform that runs JavaScript on embedded devices.
Read more about Vilic Vane