Implementation

This time, the implementation part of the design pattern is very simple and straightforward (but that could be also a good sign, right?). Let’s say there are multiple shapes in your application which should be copied at run-time and provided to the UI. Of course, it is possible to instantiate a specific shape by checking all the properties and using them to just simply create another object. However, different shapes contain different properties, they are of a different type, hence the logic just to copy a specific shape could lead to a cumbersome mess in the application code base which you probably want to avoid.

Wouldn’t it be nice to have a unified way to copy any shape in your application without even considering any details about it in your client code? Well, we have just analysed the Prototype design pattern, maybe give it a try?

Class diagram

The class diagram below shows the implementation of the Prototype design pattern:

Class Diagram — Implementation of the Prototype design pattern

Shape is an abstract class which is used as a base class for all the specific shapes. The class contains a color property and defines several abstract methods:

clone() — an abstract method to clone (copy) the specific shape;

randomiseProperties() — an abstract method to randomise property values of the shape;

render() — an abstract method to render the shape. The method is used in UI.

Circle and Rectangle are concrete shape classes which extend the abstract class Shape and implement its abstract methods.

PrototypeExample initializes and contains several Shape objects. These objects are rendered in the UI using the render() method. Also, specific shape objects could be copied using clone() and their properties could be randomised using randomiseProperties() methods respectively.

Shape

An abstract class which stores the shape’s colour and defines several abstract methods. Also, this class contains several constructors:

Shape() — a basic constructor to create a shape object with the provided colour value;

Shape.clone() — a named constructor to create a shape object as a copy of the provided Shape value.

Shapes

Circle — a specific class which defines a shape of a circle. The class defines a radius property, extends the Shape class and implements its abstract methods clone(), randomiseProperties() and render().

Rectangle — a specific class which defines a shape of a rectangle. The class defines height and width properties, extends the Shape class and implements its abstract methods clone(), randomiseProperties() and render().

Example

First of all, a markdown file is prepared and provided as a pattern’s description:

PrototypeExample contains a couple of Shape objects — Circle and Rectangle. By pressing the Randomise properties button, the values of shape’s properties are randomised (the randomiseProperties() method is called on the shape). Also, if the Clone button is pressed, the clone() method is called on the shape and a copy of that particular shape is crated with the exact same values of all the properties.

The PrototypeExample does not care about the specific type of shape object as long as it extends the Shape abstract class and implements all of its abstract methods. As a result, the clone() method could be called on any shape, all of its properties are copied even though these are different on different shapes e.g. the circle has only the radius property which is specific for that particular shape, while the rectangle has two different properties — height and width.

As you can see in the example, it does not matter of which type the specific shape is. As long as it extends the prototype base class defining the clone() method, the shape object could be copied at any time and used across your code — whether it is your business logic or UI, it is irrelevant.

All of the code changes for the Prototype design pattern and its example implementation could be found here.