Prototype Design Pattern In TypeScript (Part 1)

Hooman Momtaheni
4 min readFeb 29, 2024

--

In this series of articles, I aim to explain the exact concepts outlined in the book “Design Patterns: Elements of Reusable Object-Oriented Software”. I attempted to clarify the challenging sections using examples from the TypeScript language.

Prototype design pattern is in the category of creational patterns and its goal is specifying the kinds of objects to create using a prototypical instance, and create new objects by copying this prototype.

lets explain motivation by example.

You could build an editor for music scores (In the context of a music score editor, a “score” refers to the written or printed representation of a musical composition. It’s a visual representation of the music, typically arranged on paper or within a digital interface, that displays various musical elements such as notes, rests, dynamics, tempo markings, and more.) by customizing a general framework for graphical editors and adding new objects that represent notes, rests, and staves. The editor framework may have a palette of tools for adding these music objects to the score. The palette would also include tools for selecting, moving, and otherwise manipulating music objects.

Let’s assume the framework provides an abstract Graphic class for graphical components, like notes and staves. Moreover, it’ll provide an abstract Tool class for defining tools like those in the palette. The framework also predefines a GraphicTool subclass for tools (subclass of Tool) that create instances of graphical objects and add them to the document.

But GraphicTool presents a problem to the framework designer. The classes for notes and staves are specific to our application, but the GraphicTool class belongs to the framework. GraphicTool doesn’t know how to create instances of our music classes to add to the score. We could subclass GraphicTool for each kind of music object, but that would produce lots of subclasses that differ only in the kind of music object they instantiate.

In above example we saw that we need to have 2 subclasses (NoteTool and StaffTool) for 2 Graphic elements.

We know object composition is a flexible alternative to subclassing. The question is, how can the framework use it to parameterize instances of GraphicTool by the class of Graphic they’re supposed to create?

The solution lies in making GraphicTool create a new Graphic by copying or “cloning” an instance of a Graphic subclass. We call this instance a prototype. GraphicTool is parameterized by the prototype it should clone and add to the document. If all Graphic subclasses support a Clone operation, then the GraphicTool can clone any kind of Graphic.

What is cloning?

cloning refers to the process of creating new objects by copying or duplicating existing objects, known as prototypes.

Cloning typically involves creating a new instance of an object while preserving its state and behavior. This process is often achieved through either shallow or deep copying, depending on the requirements of the application.

Shallow cloning creates a new object and copies the properties of the original object into the new one. If the properties are primitive types, they are copied directly. However, if the properties are objects or arrays, only references to those objects or arrays are copied, not the objects themselves.

Shallow Cloning

Deep cloning creates a new object and recursively copies all properties of the original object, including nested objects and arrays, ensuring that no references are shared between the original and cloned objects.

Deep Cloning

So, in our music editor, each tool for creating a music object is an instance of GraphicTool that’s initialized with a different prototype. Each GraphicTool instance will produce a music object by cloning its prototype and adding the clone to the score.

Prototype Design Pattern Diagram
Implementation of Prototype Design Pattern in TS

We can use the Prototype pattern to reduce the number of classes even further. We have separate classes for whole notes and half notes, but that’s probably unnecessary. Instead, they could be instances of the same class initialized with different bitmaps and durations. A tool for creating whole notes becomes just a GraphicTool whose prototype is a MusicalNote initialized to be a whole note. This can reduce the number of classes in the system dramatically. It also makes it easier to add a new kind of note to the music editor.

By utilizing a prototype for both musical and non-musical products, the tool can interact with them uniformly, without requiring detailed knowledge of each product’s specific behavior. This approach not only streamlines the tool’s implementation but also minimizes the proliferation of product classes.

In next part we discuss about applications of Prototype Design Pattern.

--

--

Hooman Momtaheni

Full Stack Web Application Developer | Admire foundations and structures | Helping companies have reliable web apps and motivated software development team