As a learning exercise, I am porting an existing project from statically typed Groovy to Kotlin.
I am struggling to translate the following idiom:
@CompileStatic class Entity {
private final Map<Class<? extends Facet>, Facet> facets = [:]
public LogEntity addFacet(Facet facet) {
def type = facet.getClass() as Class<? extends Facet>
facets[type] = facet
return this
}
public <T extends Facet> T facet(Class<T> facetType) {
def f = facets[facetType]
return facetType.cast(f) as T // TODO: GROOVY-5891
}
}
// usage
def e = new Entity()
s.addFacet(new SomeData(x: 123, y: 345, ...))
s.addFacet(new SomeOtherData(a: 'abc', b: 123...))
....
assert e.facet(SomeData)?.x==123 && e.facet(SomeOtherData)?.a==‘abc’
And in Kotlin:
class Entity() {
val facets : MutableMap<Class<Facet>, Facet> = hashMapOf()
fun setFacet(facet: Facet) : LogEntity {
facets[facet.javaClass] = facet
return this
}
fun <T: Facet> facet(facet: Class<T>) : T? {
return facet.cast(facets[facet])
}
}
// usage
val e = Entity()
s.addFacet(SomeData(123, 345, …)) // can we have named arguments?
s.addFacet(SomeOtherData(‘abc’, 123…))
e.facet( ??? )
What we achieve that an entity can contain multiple facets and we can query for them and dereference them in typesafe manner, with autocompletion, etc.
I have hit a roadblock when I tried to use it and realized that I can not use class-literals in Kotlin…
Please let me know if there is some other more idiomatic way of achieving similar objective.