Factory Design Pattern

Learn about the Factory Design pattern in Kotlin, along with how to create objects without using a constructor.

The Factory Method design pattern is all about creating objects.

But why do we need a method to create objects? Isn’t that what constructors are for?

Well, constructors have limitations. As an example, imagine we’re building a game of chess. We would like to allow our players to save the state of the game into a text file and then restore the game from that position.

Since the size of the board is predetermined, we only need to record the position and type of each piece. We’ll use algebraic notation for this—for example, the Queen piece at C3 will be stored in our file as qc3, the pawn piece at A8 will be stored as pa8, and so on.

Let’s assume that we already read this file into a list of strings. Given the list of notations, we would like to populate our board with them:

// More pieces here
val notations = listOf("pa8", "qc3", ...)
val pieces = mutableListOf<ChessPiece>()
for (n in notations) {
pieces.add(createPiece(n))
}
println(pieces)
Create a list of ChessPieces from the given notations using createPiece() function

Before we can implement our createPiece function, we need to decide what’s common to all chess pieces. We’ll create an interface for that:

interface ChessPiece {
val file: Char
val rank: Char
}
Interface defining the properties of a ChessPiece with file and rank

Note that interfaces in Kotlin can declare properties, which is a very powerful feature.

Each chess piece will be a data class that implements our interface:

data class Pawn(
override val file: Char,
override val rank: Char
) : ChessPiece
data class Queen(
override val file: Char,
override val rank: Char
) : ChessPiece
Two data classes implementing ChessPiece interface

We can implement the other chess pieces same as these. Now, what’s left is to implement our createPiece function:

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")
}
}
Function to create a chess piece object based on given notation

Before we can discuss what ...