Factory pattern with companion objects in Kotlin - Time & Space Complexity
We want to understand how the time it takes to create objects using a factory pattern with companion objects changes as we ask for more objects.
How does the number of objects requested affect the work done inside the factory?
Analyze the time complexity of the following code snippet.
class Product private constructor(val name: String) {
companion object Factory {
fun create(name: String): Product {
return Product(name)
}
}
}
fun createProducts(names: List): List {
return names.map { Product.create(it) }
}
This code defines a Product class with a companion object factory method to create instances. The createProducts function makes a list of products from a list of names.
Identify the loops, recursion, array traversals that repeat.
- Primary operation: Calling the factory method
Product.createfor each name. - How many times: Once for each element in the input list
names.
Each product creation takes about the same time, so total work grows as we add more names.
| Input Size (n) | Approx. Operations |
|---|---|
| 10 | 10 calls to create |
| 100 | 100 calls to create |
| 1000 | 1000 calls to create |
Pattern observation: The work grows directly with the number of names; doubling names doubles work.
Time Complexity: O(n)
This means the time to create all products grows in a straight line with the number of products requested.
[X] Wrong: "Using a companion object factory makes object creation instant or constant time regardless of how many objects we create."
[OK] Correct: Each call to the factory still creates a new object, so the total time grows with how many objects you make.
Understanding how factory methods scale helps you explain design choices clearly and shows you think about efficiency, which is a valuable skill in real projects.
What if the factory method cached and reused existing objects instead of creating new ones? How would the time complexity change?
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
