Thursday, May 4, 2023

Prototype Design Pattern in Kotlin comparative analysis with Java

Prototype 

This design pattern is all about customization and creating objects that are similar but slightly different. To understand it better, we'll start with an example.

Building your own PC Imagine that you have a shop where you sell PCs. Regular PC consists of the components like : Motherboard CPU Graphical card RAM Most of your customers don't actually care what components you put in this PC. What they do care about is whether this PC will be able to run Magnificent to play game like Pilfering Car 7 at 60fps (which is frame per second). So, you decide to build it like that: 

data class PC(val motherboard: String = "Terasus XZ27",

             val cpu: String = "Until Atom K500",

             val ram: String = "8GB Microcend BBR5",

             val graphicCard: String = "nKCF 8100TZ")

So when a new customer comes in wanting to try out this game everybody is talking about in the neighborhood, you just do:

 val pc = PC() 

And they are already off toward home, ready to share their newest experiences from MPC7. Actually, your business goes so well that you have one PC just sitting there, ready for the next customer to come in. But then another customer arrives. And this one is tech savvy. So, frankly, they think that for the games they play, a nKCF 8100TZ graphic card wouldn't be enough at all. They've also read that there's now BBR6 RAM available and they want 16 GB of it. And of course, they want it right away. But they're willing to pay in cash. That's the moment you wish that you could just modify this PC that's sitting in your warehouse a little, instead of assembling a new one.

Starting from a prototype The whole idea of a prototype is to be able to clone an object easily. There are a number of reasons you may want to do this: Creating your object is very expensive. You need to fetch it from the database. You create objects that are similar but different from one another, and you don't want to repeat similar parts over and over again. There are also more advanced reasons to use this pattern. 

JavaScript language, for example, uses prototypes to implement inheritance-like behavior without having classes. Luckily, Kotlin fixes the broken Java clone() method. For data classes, there's the copy() method, which takes an existing data class, and creates a new copy of it, optionally changing some of its attributes in the process:

val pcFromWarehouse = PC() // Our boring PC

 val pwnerPC = pcFromWarehouse.copy(graphicCard = "nKCF 8999ZTXX",

        ram = "16GB BBR6") // Amazing PC

 println(pwnerPC) // Make sure that PC created correctly By default, the clone() method creates a shallow copy, which may be unexpected for less experienced developers. It's very hard to implement the clone() method correctly in Java. You can read about the various pitfalls at https://dzone.com/articles/shallow-and-deep-java-cloning. This is very nice article written for Java. Similar to what we've seen in the Builder design pattern, named arguments allow us to specify attributes that we can change in any order. The only thing that's left is for you to count the cash and buy some more of those nKCF graphic cards. Just in case.

Code Example :

PrototypeDesignPattern.kt :

data class PC(
val motherboard: String = "Terasus XZ27",
val cpu: String = "Until Atom K500",
val ram: String = "8GB Microcend BBR5",
val graphicCard: String = "nKFC 8100TZ"
)
fun main(args: Array<String>) {
// prototype Design pattern test

val pcFromWarehouse = PC() // Our boring PC
val pwnerPC = pcFromWarehouse.copy(
graphicCard = "nKFC 8999ZTXX",
ram = "16GB BBR6"
) // Amazing PC
println(pwnerPC)
}

Output :
PC(motherboard=Terasus XZ27, cpu=Until Atom K500, ram=16GB BBR6, graphicCard=nKFC 8999ZTXX) 



1 comment:

Anonymous said...

Very well explained!