The factory pattern helps create objects without exposing the creation logic. Companion objects in Kotlin let us put this logic inside the class itself.
Factory pattern with companion objects in Kotlin
class ClassName private constructor(val property: Type) { companion object { fun create(param: Type): ClassName { // creation logic return ClassName(param) } } }
The constructor is private to prevent direct creation from outside.
The companion object acts like a static factory inside the class.
class User private constructor(val name: String) { companion object { fun create(name: String): User { return User(name) } } }
class Shape private constructor(val type: String) { companion object { fun createCircle(): Shape = Shape("Circle") fun createSquare(): Shape = Shape("Square") } }
This program uses the factory pattern with companion objects to create Vehicle objects. The constructor is private, so you must use the factory methods to create vehicles.
class Vehicle private constructor(val type: String) { companion object { fun createCar(): Vehicle = Vehicle("Car") fun createBike(): Vehicle = Vehicle("Bike") } } fun main() { val car = Vehicle.createCar() val bike = Vehicle.createBike() println("Vehicle 1 is a ${car.type}") println("Vehicle 2 is a ${bike.type}") }
Using private constructors ensures objects are only created through factory methods.
Companion objects let you group factory methods inside the class for better organization.
This pattern helps keep object creation flexible and easy to change later.
The factory pattern controls object creation.
Companion objects in Kotlin provide a neat place for factory methods.
Private constructors prevent direct object creation, enforcing use of factories.
Practice
companion object in Kotlin's factory pattern?Solution
Step 1: Understand companion objects
Companion objects in Kotlin are used to hold methods and properties related to the class but not tied to an instance.Step 2: Role in factory pattern
In the factory pattern, companion objects provide factory methods to create instances, especially when constructors are private.Final Answer:
To provide a place for factory methods that create instances -> Option AQuick Check:
Companion object = factory methods [OK]
- Thinking companion objects store instance variables
- Confusing companion objects with inheritance
- Believing companion objects allow multiple constructors
Solution
Step 1: Recall Kotlin constructor syntax
In Kotlin, the constructor keyword follows the class name, and modifiers like private come before constructor.Step 2: Identify correct placement
The correct syntax places 'private' before 'constructor()' right after the class name.Final Answer:
class MyClass private constructor() {} -> Option BQuick Check:
Private constructor syntax = class MyClass private constructor() {} [OK]
- Placing 'private' after constructor parentheses
- Putting 'private' before class keyword
- Misordering 'constructor' and 'private'
class Product private constructor(val name: String) {
companion object {
fun create(name: String): Product {
return Product(name)
}
}
}
fun main() {
val p = Product.create("Book")
println(p.name)
}Solution
Step 1: Understand private constructor usage
The class Product has a private constructor, so instances cannot be created directly outside the class.Step 2: Use of companion object factory method
The companion object provides a create() method that calls the private constructor and returns a Product instance.Step 3: Output of main function
In main(), Product.create("Book") creates an instance with name "Book". Printing p.name outputs "Book".Final Answer:
Book -> Option AQuick Check:
Factory method returns instance with name "Book" [OK]
- Expecting compilation error due to private constructor
- Thinking create() returns null
- Confusing runtime exception with private constructor
class User private constructor(val id: Int) {
companion object {
fun create(id: Int): User {
User(id)
}
}
}Solution
Step 1: Check create() method body
The create() method calls User(id) but does not return the created object.Step 2: Understand Kotlin function return rules
Functions must explicitly return a value unless they are Unit (void). Here, create() should return the new User instance.Final Answer:
Missing return statement in create() method -> Option DQuick Check:
Factory method must return created object [OK]
- Assuming constructor can't be private for companion access
- Placing factory method outside companion object
- Forgetting return keyword in factory method
class Device private constructor(val model: String) {
companion object {
fun create(model: String): Device {
return Device(model)
}
}
}Solution
Step 1: Understand the problem
The factory method should handle invalid input by returning a default instance instead of failing.Step 2: Modify create() method
Add a check: if model is empty, return Device("Unknown"), else return Device(model).Step 3: Why this works
This approach keeps constructor private, centralizes instance creation, and handles invalid input gracefully.Final Answer:
Add a condition in create() to return Device("Unknown") if model is empty -> Option CQuick Check:
Factory method handles invalid input with default instance [OK]
- Making constructor public defeats factory pattern
- Throwing exception instead of default instance
- Removing companion object loses factory benefits
Ready to prove it?
Pass the test and this pattern moves unknown
