Kotlin Prototype: A closer look to the Prototype Design Pattern in Kotlin
The Prototype pattern is a creational design pattern, it means its job is to create or build objects. If you already have written some apps, or even some lines of code in Kotlin, you might already have used the Prototype Design Pattern and you might not even know!
Motivation
Class instantiation is expensive from a computational point of view. Imagine the situation where you need to create a vast number of grass or stone sprites in a video game. Object creation may be also an ardue task if it needs an important amount of information. Your code might also require an extra of dependencies to reach that essential information. That could cause code smell or make it rigid in many ways. Therefore, the pattern was born to solve such situations. It permits the creation of an object prototype, a starting point from where to start cloning instances of itself.
Adoption
There are several languages out there that offer support to define or implement the Prototype pattern based on developer needs or expectations. For example, Java using the clone method or C++ through its copy constructor.
Usage in Kotlin
If you are an Android developer with Jetpack Compose experience, you might probably have dealt with states. Specially for compose states, we are not used to create a new state from scratch every time it changes, we make a copy of it. Kotlin allows you to create copies of data classes. It also offers you the mechanism to alter some field values when copying. In fact, it comes very handy when dealing with states.
Despite the fact that copy method of a data class lets you clone objects, it’s not strictly a direct implementation of the Prototype pattern. Although it shares similarities with the Prototype pattern in terms of creating copies of objects, it lacks of abstraction.
Confused?
Actual implementation
The actual implementation of the Prototype pattern in Kotlin might differ from the simple fact of copying a data object. A proper implementation of the pattern should allow you clone an object regardless its type, that’s what a prototype is all about.
Let’s take a look at the Shape interface, this will be our cloneable prototype.
Square and Circle shape classes implement the Shape prototype
Abstraction
A Shape must be able to be cloned. Each implementation is then forced to offer a copy feature. Any client of Shape interface is capable of cloning it, no matter its concretion.
Prototype + data class
A combination of the Prototype pattern and the data class copy feature is also a smart solution. Large classes can then be cloned through the pattern by just calling the copy function.
Conclusions
Data class copy feature is simply a mechanism of duplicating data objects. It might not be that flexible when dealing with massive object cloning, specially with large variety of data types. On the other hand, the Prototype pattern may get advantages of the copy feature as it simplifies the implementation boilerplate.
The Prototype Design Pattern do not differ much among programming languages. One of its main goal is to decouple your logic from concrete classes that are intended to be cloned. It may also reduce the verbose and complexity of inheritance handicap when applying copying technics.