gbattez
December 13, 2017, 3:47pm
1
Let’s say there I have an interface named “Focusable”, and an object “FocusableManager”
the manager has a list of Focusables and I want that this list grows as Focusable objects are created.
The solution is then to provide a factory method, but what’s the best convention for it? do I put it in FocusableManager or in the Focusable interface like so?
interface Focusable {
companion object {
fun create(focusable: Focusable): Focusable {
FocusableManager.list.add(focusable)
return focusable
}
}
}
edit: Is there even better ways to do that than factory methods?
The Kotlin way is to define a top-level constructor function for your interface with the same name as your interface:
fun Focusable(focusable: Focusable): Focusable {
FocusableManager.list.add(focusable)
return focusable
}
Although, a constructor function (or a function named create
) with side effect is a very, very bad code smell.
gbattez
December 19, 2017, 9:41am
3
Thanks, I’m working a on small project alone so that would do it fine, but If that’s not a very good way of achieving this, then what would be one?
jstuyts
December 19, 2017, 9:57am
4
Use an interface for Focusable
factories, and implement a decorator that registers the created Focusable
with the manager:
interface Focusable
interface FocusableManager {
fun add(focusable: Focusable)
}
object DummyFocusableManager : FocusableManager {
override fun add(focusable: Focusable) {
println("Added: $focusable")
}
}
interface FocusableFactory {
fun create(): Focusable
}
class FocusableRegisteringFactory(private val delegatee: FocusableFactory,
private val manager: FocusableManager) : FocusableFactory {
override fun create(): Focusable {
val result = delegatee.create()
manager.add(result)
return result
}
}
class FirstFocusableImplementation : Focusable {
companion object : FocusableFactory {
override fun create() = FirstFocusableImplementation()
}
}
class SecondFocusableImplementation : Focusable {
companion object : FocusableFactory {
override fun create() = SecondFocusableImplementation()
}
}
fun main(args: Array<String>) {
val firstFactory = FocusableRegisteringFactory(FirstFocusableImplementation.Companion, DummyFocusableManager)
val secondFactory = FocusableRegisteringFactory(SecondFocusableImplementation.Companion, DummyFocusableManager)
println("Created: ${firstFactory.create()}")
println("Created: ${secondFactory.create()}")
}