26
Design Patterns: Prototype
Prototype?
Your probably thinking of this:

or maybe even this:

I would love to make an article about how amazing Prototype the game is. But unfortunately we are on a design pattern series. Instead we are going to cover the Prototype Design Pattern.
Today you will learn:

The Prototype Pattern is a creational design pattern that allows us to clone objects without having to depend on their underlying classes.
But why would we want to clone objects?
Well, there might be certain situations where you might need to clone an object:
Car
object, and have them all go to separate paths and pick the best.Person
at that moment. It would be wise to create a clone of Person
first and then take its date of birth because there is a slight chance that it would be modified by some other code.PS. Cloning is not the same thing as copying. There are in-fact two types of copying:
Let's imagine that your working on a blogging platform where people can create and share their articles. One day, your product owner comes and tells you that you will have to implement the duplicate article feature.
You say it's pretty simple, and begin working.
You come up with a naive solution:
class Article {
public title;
public body;
private created_at;
constructor(title, body, created_at){
this.title = title;
this.body = body;
this.created_at = created_at;
}
}
class Client {
Article article;
constructor(Article article){
this.article = article;
}
public Article duplicate(){
const clone = new Article();
clone.title = this.article.title;
clone.body = this.article.body;
}
}
Do you see the problem?
We created a new
Article
object and copied the title and body from the initial object to the copied one, but what about the created_at
field? We can't simply copy it over because it's a private field. A solution would be to simply make it public but this is bad practice.
Another problem is that our client is now coupled together with the
Article
class, if we want to copy an object of another class, we will have to create this whole process again, but for a different class. We can do better.
The prototype pattern delegates the cloning to the actual object.
But first let us create a common interface for all objects that are clonable.
interface Cloneable {
public clone()
}
Now that that's done let us refactor our
Article
class to use this interface.class Article implements Cloneable {
public title;
public body;
private created_at;
constructor(title, body, created_at){
this.title = title;
this.body = body;
this.created_at = created_at;
}
public clone(){
const clone = new Article(this.title, this.body, this.created_at);
return clone;
}
}
Our
Article
class now has a clone method which returns for use a clone of the current object. In our
Client
class we can simply:class Client {
Article article;
constructor(Article article){
this.article = article;
}
public Article duplicate(){
return this.article.clone();
}
}
Simple enough, this is the basic premise of the prototype pattern. Keep in mind that this is already implemented out of the box in most programming languages, so you don't have to implement this yourself, but it's good to know how things work under the hood.
This is the simplest design pattern we have covered so far, but don't forget:
"Knowing is Half the Battle"
Take a step further and see ways in your own projects where you would use this pattern.
Today you learned:
Thanks for reading!
If you want to learn more about the design patterns, I would recommend Diving into Design Patterns. It explains all 23 design patterns found in the GoF book, in a fun and engaging manner.
Another book that I recommend is Heads First Design Patterns: A Brain-Friendly Guide, which has fun and easy-to-read explanations.
26