I am new to Kotlin and want to know how to solve the following problem in the most idiomatic way with this language.
Let's say we have the base class Symbol
and a bunch of its subclasses: SymbolA
, SymbolB
, and so on. We receive a list of symbols (instances of Symbol
subtypes) and want to do some action on each symbol depending on its type. Assume also that we are planning to add more subclasses of Symbol
and more new kinds of actions on them in future.
Example
For example, we was asked to transform each symbol in the list with the transformation corresponding to the type of symbol (assume that the transformation is fixed for each type). I will list the possible sollutions appearing in mind.
Possible Approach 1
Maybe the simplest possible approach is to declare the following abstract method in Symbol
class:
open class Symbol {
/*...*/
abstract fun transform() -> Symbol
}
so that each derived class should implement its corresponding transformation inside the transform()
method. The problem with this approach, I think, is that we have mixed the internals of Symbol
s with the logic that operates on the data. What if we will be asked to add few more similar actions and so on? I think that this is exactly the case when we would like to decouple the operations from the data.
Possible Approach 2
The second approach I thought of is to use the visitor pattern. It looks nice, however, as far as I understand, it becomes problematic when we would decide to introduce additional Symbol
s (subclasses of Symbol
).
Possible Approach 3
Use type introspection (e.g. Kotlin
's is
, or Java
's instanceof
operator). For example, we can do the following:
fun transform(symbol: Symbol) : Symbol {
return when(symbol) {
is SymbolA -> /* perform the transformation of SymbolA */
is SymbolB -> /* perform the transformation of SymbolB */
...
else -> TODO("Transformation is not implemented for: ${symbol::class}")
}
}
Possible Approach 4
Use reflection. We can introduce the following interface:
interface Transformation <T: Symbol> {
fun transform(symbol: T) -> Symbol
}
Then implement the corresponding transormation for each subclass of Symbol
and use a heterogeneous map to set/get the transformation corresponding to the type of symbol. I would also expect for this solution to be the slowest one compared to the previous solutions.
Summary
What I want to know:
- Any other related solution (pattern) I am not aware of?
- Which one is the most flexible and maintainable solution to this particulat problem?
- Which solution is most idiomatic/natural for
Kotlin
language?
Thanks in advance!
Aucun commentaire:
Enregistrer un commentaire