Prototype#

In the prototype pattern, a new object is created by cloning an existing object. In Java, the clone() method is an implementation of this design pattern.

The prototype pattern can be a useful way of creating copies of objects. One example of how this can be useful is if an original object is created with a resource such as a data stream that may not be available at the time that a clone of the object is needed. Another example is if the original object creation involves a significant time commitment, such as reading data from a database. An added benefit of the prototype pattern is that it can reduce class proliferation in a project by avoiding factory proliferation.

To understand this, let’s break it down:

  • Class proliferation: This refers to having too many classes in a project, which can make the code harder to understand, maintain, and extend.

  • Factory proliferation: This refers to having too many factory classes. A factory class is a class responsible for creating objects of other classes. If you have a lot of different types of objects to create, you might end up with a lot of factory classes, which can also make the code more complex.

We can implement our own prototype pattern. To do so, we’ll create a Prototype interface that features a doClone() method.

Prototype interface with implementations#
public interface Prototype {
   public Prototype clone();
}

//===

public class Person implements Prototype {
    String name;

    public Person(String name) {
        this.name = name;
    }

    @Override
    public Prototype clone() {
        return new Person(name);
    }

    public String toString() {
        return name;
    }
}

//===

public class Cat implements Prototype {
    String sound;
    Person belongsTo;

    public Cat(String sound) {
        this.sound = sound;
    }

    @Override
    public Prototype clone() {
        return new Cat(sound, belongsTo.clone());
    }

    public String toString() {
        return "This cat says " + sound + " and belongs to " + belongsTo;
    }
}
Prototype pattern implementation in Python#
 import copy

 class Prototype:
     def clone(self):
         return copy.deepcopy(self)

 class Person(Prototype):
     def __init__(self, name):
         self.name = name

     def __str__(self):
         return self.name

 class Cat(Prototype):
     def __init__(self, sound: str, belongs_to: Person):
         self.sound: str = sound
         self.belongs_to: Person = belongs_to

     def __str__(self):
         return f"This cat says {self.sound} and belongs to {self.belongs_to}"

In this example, Person and Cat classes inherit from the Prototype class and use the clone method to create a new instance of themselves. The deepcopy function is used to ensure that all parts of the object are cloned, not just the top-level object.