Saturday, October 22, 2022

Design Pattern in Kotlin - Factory Method

Factory Patter certainly in Kotlin

For those in need of a reminder, the factory is a creational pattern listed in the book commonly referred to as “the GOF”. 

The GoF book defines the intent of Factory Method as:

Define an interface for creating an object, but let subclasses decide which class to instantiate. Factory Method lets a class defer instantiation to subclasses.

If you haven’t heard or read about it, there’s still time to catch up. don’t hesitate to google the world of patterns; there are plenty of resources available on the internet (and Wikipedia is a satisfactory one for a quick introduction).

However I like to code as give me anything I will come up with a code which will be simple and efficient. So I have created a simple program to understand the Factory Patter certainly in Kotlin.  How it works in Kotlin. You can also go through my java article about Factory pattern for detail understand and can also do comparison .

https://androidcodingworld.blogspot.com/2016/05/creational-design-patterns.html

 Please refer below.

 Code Example :

fun main() {

    val queen = createPiece("qa5")

    println(queen)

}

interface ChessPiece {

    val file: Char

    val rank: Char

}

data class Pawn(

    override val file: Char,

    override val rank: Char

) : ChessPiece


data class Queen(

    override val file: Char,

    override val rank: Char

) : ChessPiece

fun createPiece(notation: String): ChessPiece {

    val (type, file, rank) = notation.toCharArray()

    return when (type) {

        'q' -> Queen(file, rank)

        'p' -> Pawn(file, rank)

        else -> throw RuntimeException("Unknown piece: $type")

    }

}

This is how Factory works in  Kotlin Design Pattern

Output : 

Positive Use Case

Queen(file=a, rank=5)

Negative Use- Case:

Exception in thread "main" java.lang.RuntimeException: Unknown piece: t

at MainKt.createPiece(Main.kt:28)

at MainKt.main(Main.kt:2)

at MainKt.main(Main.kt)

Lets take another simple example :

fun main() {
val genre = "SCIENCE"
val book = BookFactory.createbook(
when (genre) {
"SCIENCE" -> Genre.SCIENCE
"MATH" -> Genre.MATH
else -> {
throw RuntimeException("There is no such genre")
}
}
)
println("Getting Book Info")
book.getInfo()
println("Order Book Info")
book.order()
println("Rate Book Info")
book.rate()
}

interface Book {
fun getInfo()
fun order()
fun rate()
}

enum class Genre {
SCIENCE, MATH
}

class BookFactory {
companion object {
fun createbook(genre: Genre): Book = when (genre) {
Genre.SCIENCE -> object : Book {
override fun getInfo() {
println("Law of Motion - Physics")
}

override fun order() {
println(" Ordder for Law of Motion - Physics")
}

override fun rate() {
println("Rate for Law of Motion - Physics")
}
}
Genre.MATH -> object : Book {
override fun getInfo() {
println("Abhinaw Tripathi - Math")
}

override fun order() {
println(" Order for Law of Motion - Math")
}

override fun rate() {
println("Rate for Law of Motion - Math")
}
}
}
}
}

Output : 

Getting Book Info

Law of Motion - Physics

Order Book Info

 Ordder for Law of Motion - Physics

Rate Book Info

Rate for Law of Motion - Physics

All of these are example related to Factory Method Design Pattern . These are certainly designed with reference to Kotlin.

Now lets take another example bit of Java style / oriented :

fun main() {
val factory = VirusFactory()
val virus = factory.makeVirus(VirusType.CORONA_VIRUS)
virus.spread()
virus.mutate()
}

interface Virus {
fun mutate()
fun spread() {
println("Spreading the virus...")
}
}

enum class VirusType {
CORONA_VIRUS, INFLUENZA, HIV
}

class CoronaVirus : Virus {
override fun mutate() {
println("Mutating the corona virus...")
}
}

class InfluenzaVirus : Virus {
override fun mutate() {
println("Mutating the flu virus...")
}
}

class HIVVirus : Virus {
override fun mutate() {
println("Mutating the HIV virus...")
}
}

class VirusFactory {
fun makeVirus(type: VirusType): Virus {
return when (type) {
VirusType.CORONA_VIRUS -> CoronaVirus()
VirusType.INFLUENZA -> InfluenzaVirus()
VirusType.HIV -> HIVVirus()
}
}
}

Output :

Spreading the virus...

Mutating the corona virus...

Thank you.