Factory Pattern in Kotlin
Factory Pattern in Kotlin
The Factory Pattern is a creational design pattern that delegates object construction to a dedicated method or class instead of calling constructors directly. In Kotlin, the pattern takes several idiomatic forms, including companion object factory methods, sealed class hierarchies, and top level factory functions. The pattern decouples client code from concrete implementations, making it easier to introduce new types without modifying existing consumers. By the end of this lesson, you will be able to:
- Explain the purpose of the factory pattern and how it differs from direct construction.
- Implement factory methods using Kotlin companion objects and sealed classes.
- Apply the abstract factory pattern to create families of related objects.
- Identify when the factory pattern adds value versus when direct construction is simpler.
Factory Method with Companion Objects
Kotlin's companion objects provide a natural home for factory methods. Unlike Java, where static factory methods live directly on the class, Kotlin uses a companion object that can implement interfaces and hold state. The invoke operator or named factory methods on the companion object are common patterns:
interface Logger {
fun log(message: String)
}
class ConsoleLogger private constructor() : Logger {
override fun log(message: String) {
println("[CONSOLE] $message")
}
companion object {
fun create(): Logger = ConsoleLogger()
}
}
class FileLogger private constructor(
private val path: String
) : Logger {
override fun log(message: String) {
File(path).appendText("$message\n")
}
companion object {
fun create(path: String): Logger = FileLogger(path)
}
}
The constructors are private, so the only way to obtain an instance is through the factory method. This lets each class validate arguments, cache instances, or return a subtype without exposing those decisions to the caller.
Sealed Class Hierarchies as Factories
Sealed classes in Kotlin combine well with the factory pattern because the compiler enforces exhaustive when expressions. A single factory method can return any subtype, and callers can handle each case without casting:
This interview continues for subscribers
Subscribe to Dove Letter for full access to exclusive interviews about Android and Kotlin development.
Become a Sponsor