Niko
12/13/2021, 1:33 PMmath
, series
, sports-science
) into their distinct Gradle packages, and use them as dependencies in other projects/modules, as needed. All the logic is framework-agnostic, meaning non of the logic rely on any (database) ID information, nor have they any representation-only information, but are pure data classes.
My question relates to the issue of using said modules' data classes in an Android project (with SQLDelight) [also posted to squarelibraries a narrower question]:
What would be the best way to use and extend the functionalities of the library-code data classes
(a) without opening them as by default Kotlin keeps them closed for extension
(b) avoiding writing some wrapper types that just take the lib class as constructor parameter, along with ID and persistence timestamp information etc? That would result in writing much redundant boilerplate code just to delegate each method call to the private scoped constructor parameter type or having to write an additional X.value.something()
calls to public parameter.
If I extracted interfaces of all of the exported types, I could then possibly just use interfaces and delegation, like
// lib project
interface A {
val name: String
val value: Int
fun foo(): String
}
data class AImpl(override val name: String, override val value: Int) : A {
override fun foo() = "<$name><$value>"
}
// UI project
@JvmInline
value class Id<T>(val id: Int)
data class UiA(val id: Id<UiA>, private val a: A) : A by a
fun main() {
val a1 = AImpl("A", 1)
val a2 = UiA(Id(1), a1)
println(a2) // >> UiA(id=Id(id=1), a=AImpl(name=A, value=1))
println(a2.foo()) // >> <A><1>
}
but then I would end up with many interface A
+ data class AImpl
pairs for types with single implementation (is this a non-issue?)