Design Pattern: Prototype Pattern in TypeScript

Prototype pattern use the existing object, to create a new object(of the same type), by cloning the existing object. This process will reduce resource usage, and makes object creation easier.

This article demonstrates Prototype pattern implementations in TypeScript. Check the implementation details and following examples.

Implementation

There are a few ways in which we can implement a prototype in TypeScript. Let’s take a look at the methods.

Method #1: Using Object.create()

The simplest way to create an object from an existing object, using the existing object prototype, is to use “Object.create()” method, like below-

let clonedObj = Object.create(someExistingObject);

Just passing any existing object to the method will create a new object, with the same prototype.

Method #2: clone() method implementation

Here are the key points of Prototype pattern implementation in TS by adding a clone method to the object. –

  • First thing we need is an interface. We can name the interface as “Prototype”.
  • Declare a method named “clone”, which has a return type of the type “Prototype”.
  • Then for the item classes, we need to implement the “Prototype” interface. In the clone method create a new object of the same class and return it.
  • While using the item object, if we need another object we can just call the “clone” method of the object and we will get a new object.

Cast the obtained object as the item by adding “<ItemClass>” in front of the clone. This is required as the returned object from “clone” method is of type “Prototype” and we need to cast to use the full functionality of the item object type.

Simple implementation of Prototype pattern in TypeScript-

// Prototype interface
interface Prototype {
    clone(): Prototype;
}

// Item class
class Item implements Prototype {
    property1: number;
    property2: number;

    constructor(property1: number, property2: number) {
        this.property1 = property1;
        this.property2 = property2;
    }

    clone(): Prototype {
        return new Item(this.property1, this.property2);
    }
}

// Prototype object cloning demo
const originnalItem = new Item(123, 456);
console.log("Original Item:", originnalItem);

// Clone the original object
let cloneItem = <Item>originnalItem.clone();
console.log("Clone Object just after cloning:", cloneItem);

cloneItem.property1 = 8888;
cloneItem.property2 = 9999;

console.log("Clone Object after prop change:", cloneItem);

// check if original object is changed
console.log("Original Object after cloning process:", originnalItem);

Here inside the clone method, we have used the “new” keyword for generating a new object of the class. Instead of this, you can also use “Object.create(this)” inside the clone method.

This will generate the following output-

Original Item: Item { property1: 123, property2: 456 }

Clone Object just after cloning: Item { property1: 123, property2: 456 }

Clone Object after prop change: Item { property1: 8888, property2: 9999 }

Original Object after cloning process: Item { property1: 123, property2: 456 }

Examples

Here are a few examples of Prototype pattern implementation and usage.

Example #1: Transport

Here we are demonstrating prototype implementation for different vehicles, like Car, Plane etc.

Prototype Interface

  • Create file “prototype.ts”.
  • Define an interface named “Prototype”.
  • Declare a method named “clone”, which has return type of “Prototype”.
// transport.ts

interface Prototype {
    clone(): Prototype;
}

export default Prototype;

Car Class [Item Class]

  • Create file “car.ts”.
  • Define class named “Car”.
  • Define properties as per requirement. Here we have – “make”, “model”, and “color”.
  • Define the constructor as per the requirement of the item class. Here we are accepting the values and setting those to the properties.
  • Implement “Prototype” interface. Define “clone” method in the class. In the method create a new “Car” object and return that.
// car.ts

import Prototype from "./prototype";

class Car implements Prototype {
    make: number;
    model: string;
    color: string;

    constructor(make: number, model: string, color: string) {
        this.make = make;
        this.model = model;
        this.color = color;
    }

    clone(): Prototype {
        return new Car(this.make, this.model, this.color);
    }

    toString(): string {
        return "Make: " + this.make + " | Model: " + this.model + " | Color: " + this.color;
    }
}

export default Car;

Plane Class

  • Create file “plane.ts”.
  • Define class “Plane”.
  • Define properties according to the requirement. Here we have – “model” and “color”.
  • Create a constructor according to the requirement. Here we have accepted the prop value and set those in the constructor.
  • Implement “Prototype” interface. Define “clone” method, and in the method create a new “Plane” object.
// plane.ts

import Prototype from "./prototype";


class Plane implements Prototype {
    model: string;
    color: string;

    constructor(model: string, color: string) {
        this.model = model;
        this.color = color;
    }

    clone(): Prototype {
        return new Plane(this.model, this.color);
    }

    toString(): string {
        return "Model: " + this.model + " | Color: " + this.color;
    }
}

export default Plane;

Demo

  • Create file “demo.ts”.
  • Create a new “Car” object by passing the required values, and save the object in “carOriginal” variable.
  • Now call the clone method of “carOriginal” and cast it as “Car” by using code “<Car>carOriginal.clone()”.
  • We can change the values, or use the clone object in any other way, as per our requirement.

Changing the properties of the clone object will not change the original object, and vice-versa.

// demo.ts

import Car from "./car";


let carOriginal = new Car(2014, "ABCD", "Red");
console.log("Original Car:", carOriginal);


var carClone = <Car>carOriginal.clone();
carClone.model = "Some Different Model";
carClone.color = "White";

console.log("Clone Car:", carClone);

// check if original value is changed
console.log("Original Car after clone:", carOriginal);

Output

The output of demo code will be as below-

Original Car: Car { make: 2014, model: 'ABCD', color: 'Red' }

Clone Car: Car { make: 2014, model: 'Some Different Model', color: 'White' }

Original Car after clone: Car { make: 2014, model: 'ABCD', color: 'Red' }

Source Code

Use the following link to get the source code:

Other Code Implementations

Use the following links to check Prototype pattern implementation in other programming languages.

Leave a Comment


The reCAPTCHA verification period has expired. Please reload the page.