Design Patterns - Prototype
Tags: kotlin, kotlinbeginners, designpatterns, cleancode
Published: 2023-11-20 11:17:26

---
title: Design Patterns - Prototype
published: true
date: 2023-11-20 09:49:55 UTC
tags: kotlin,KotlinBeginners,DesignPatterns,CleanCode
canonical_url: https://yonatankarp.com/design-patterns-prototype
---

> **TL;DR:** The Prototype design pattern creates new objects by cloning a prototypical instance, allowing you to modify the copy without creating an object from scratch. This pattern is useful when object creation is expensive or when classes to instantiate are specified at runtime.

## Intent

Specify the kinds of objects to create using a prototypical instance, and create new objects by copying this prototype.

## Explanation

First, it should be noted that the Prototype pattern is not used to gain performance benefits. It's only used for creating new objects from prototype instances.

Real-world example

> Remember Dolly? The sheep that was cloned! Let's not get into the details but the key point here is that it is all about cloning.

In plain words

> Create an object based on an existing object through cloning.

Wikipedia says

> The prototype pattern is a creational design pattern in software development. It is used when the type of objects to create is determined by a prototypical instance, which is cloned to produce new objects.

In short, it allows you to create a copy of an existing object and modify it to your needs, instead of going through the trouble of creating an object from scratch and setting it up.

**Programmatic Example**

In Kotlin, the prototype pattern is recommended to be implemented as follows. First, create an interface with a method for cloning objects. In this example, `Prototype` interface accomplishes this with its `clone` method. We will then use the `copy()` function of data class to create a clone of our class where we can override specific fields of the class if needed.

```kotlin
abstract class Prototype<T> {
  abstract fun clone(): T
}
```

Our example contains a hierarchy of different creatures. For example, let's look at `Beast` and `OrcBeast` classes.

```kotlin
abstract class Beast : Prototype<Beast>()

data class OrcBeast(private val weapon: String) : Beast() {

  override fun clone() = copy()

  override fun toString() = "Orcish wolf attacks with $weapon"
}
```

We don't want to go into too many details, but the full example contains also base classes `Mage` and `Warlord` and there are specialized implementations for those for elves in addition to orcs.

To take full advantage of the prototype pattern, we create `HeroFactory` class to produce different kinds of creatures from prototypes.

```kotlin
class HeroFactory(
  private val mage: Mage,
  private val warlord: Warlord,
  private val beast: Beast,
) {
  fun createMage() = mage.clone()

  fun createWarlord() = warlord.clone()

  fun createBeast() = beast.clone()
}
```

Now, we can show the full prototype pattern in action producing new creatures by cloning existing instances.

```kotlin
var factory = HeroFactory(
  ElfMage("cooking"),
  ElfWarlord("cleaning"),
  ElfBeast("protecting")
)

var mage = factory.createMage()
var warlord = factory.createWarlord()
var beast = factory.createBeast()

logger.info(mage.toString())
logger.info(warlord.toString())
logger.info(beast.toString())

factory = HeroFactory(
  OrcMage("axe"),
  OrcWarlord("sword"),
  OrcBeast("laser")
)

mage = factory.createMage()
warlord = factory.createWarlord()
beast = factory.createBeast()

logger.info(mage.toString())
logger.info(warlord.toString())
logger.info(beast.toString())
```

Here's the console output from running the example.

```kotlin
Elven mage helps in cooking
Elven warlord helps in cleaning
Elven eagle helps in protecting
Orcish mage attacks with axe
Orcish warlord attacks with sword
Orcish wolf attacks with laser
```

## Class diagram

![](https://cdn.hashnode.com/res/hashnode/image/upload/v1700473254933/1d7d62ab-cbb3-4d17-8efb-b52d017e44f0.png)

## Applicability

Use the Prototype pattern when a system should be independent of how its products are created, composed, represented and

- When the classes to instantiate are specified at run-time, for example, by dynamic loading.

- To avoid building a class hierarchy of factories that parallels the class hierarchy of products.

- When instances of a class can have one of only a few different combinations of state. It may be more convenient to install a corresponding number of prototypes and clone them rather than instantiating the class manually, each time with the appropriate state.

- When object creation is expensive compared to cloning.

* * *

I hope you enjoyed this journey and learned something new. If you want to stay updated with my latest thoughts and ideas, feel free to register for my [**newsletter**](https://yonatankarp.com/newsletter). You can also find me on [**LinkedIn**](https://www.linkedin.com/in/yonatankarp/) or [**Twitter**](https://twitter.com/yonatan_karp). Let's stay connected and keep the conversation going!

* * *

## **Code Examples**

All code examples and tests can be found in the [**Kotlin Design Patterns repository**](https://github.com/yonatankarp/kotlin-design-patterns/tree/main/prototype)

## Credits

- [Java Design Patterns](https://github.com/iluwatar/java-design-patterns)

- [Design Patterns: Elements of Reusable Object-Oriented Software](https://www.amazon.com/gp/product/0201633612/ref=as_li_tl?ie=UTF8&camp=1789&creative=9325&creativeASIN=0201633612&linkCode=as2&tag=javadesignpat-20&linkId=675d49790ce11db99d90bde47f1aeb59)

- [Head First Design Patterns: A Brain-Friendly Guide](https://www.amazon.com/gp/product/0596007124/ref=as_li_tl?ie=UTF8&camp=1789&creative=9325&creativeASIN=0596007124&linkCode=as2&tag=javadesignpat-20&linkId=6b8b6eea86021af6c8e3cd3fc382cb5b)