Last active
January 21, 2024 07:45
-
-
Save LouisCAD/8ec67b6473e98d28f4609ac31869c80f to your computer and use it in GitHub Desktop.
Demonstration of the powers of companion objects when it comes to discoverability. Great alternative to java-style "factories".
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
package i_love_companion_objects | |
suspend fun main() { | |
// Discoverability is easy with the companion object | |
// (although autocomplete could use some performance improvements...) | |
doStuff(SomeInterface.createWithDefaults()) | |
val someInstance: SomeInterface = SomeInterface.create( | |
parameterOne = 0, | |
parameterTwo = 1 | |
) | |
doStuff(someInstance) | |
doStuff(SomeInterface.appInstance) | |
} | |
// This is a random function that would need an instance of SomeInterface. | |
private suspend fun doStuff(someInterface: SomeInterface) { | |
someInterface.someFunction() | |
} | |
// Extension property on the companion object, easy to discover. | |
val SomeInterface.Companion.appInstance: SomeInterface get() = someInterfaceAppInstance | |
private val someInterfaceAppInstance = SomeInterface.create(0, 0) |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
package i_love_companion_objects | |
interface SomeInterface { | |
companion object; // Semicolon needed to avoid next word ("suspend" in this case) | |
// being picked up as the companion object name. | |
// BTW, here, we keep the default one, which is "Companion". | |
// This is a random function, we don't really care about it, the focus is companion objects. | |
suspend fun someFunction() | |
} |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
package i_love_companion_objects | |
// Extension function on the companion object, easy to discover. Can use any name. | |
fun SomeInterface.Companion.create( | |
parameterOne: Any, | |
parameterTwo: Any | |
): SomeInterface { | |
return SomeInterfaceImpl( | |
parameterOne = parameterOne, | |
parameterTwo = parameterTwo | |
) | |
} | |
private class SomeInterfaceImpl( | |
private val parameterOne: Any, | |
private val parameterTwo: Any | |
) : SomeInterface { | |
override suspend fun someFunction() { | |
println("FYI: someFunction called in $javaClass with some parameters :)") | |
} | |
} |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
package i_love_companion_objects | |
import kotlinx.coroutines.* | |
// Extension function on the companion object, easy to discover. Can be suspending. | |
suspend fun SomeInterface.Companion.createWithDefaults(): SomeInterface { | |
return SomeInterfaceOtherImpl( | |
someParameter = pretendToDoSomeWorkAndReturnIt() | |
) | |
} | |
// Looks like a constructor, but suspends. Could take any parameters, can have overloads. | |
suspend operator fun SomeInterface.Companion.invoke(): SomeInterface { | |
return createWithDefaults() | |
} | |
private suspend fun pretendToDoSomeWorkAndReturnIt(): Any { | |
return delay(timeMillis = 10) | |
} | |
// Implementation is hidden, no need to guess its name. | |
private class SomeInterfaceOtherImpl( | |
private val someParameter: Any | |
) : SomeInterface { | |
override suspend fun someFunction() { | |
println("FYI: someFunction called in $javaClass having someParameter set to $someParameter") | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment