У меня есть следующие классы:
sealed class A : BaseType
sealed class B : BaseType
sealed class C : BaseType
...
Если у меня есть метод processObject
, который выглядит следующим образом:
fun processObject(obj: BaseType): Int {
return when(obj) {
is A -> 1
is B -> 1
else -> 0
}
}
Я заметил, что сейчас повторяюсь, поэтому я мог бы изменить этот метод на что-то вроде этого:
fun processObject(obj: BaseType): Int {
return when(obj) {
is A, is B -> 1
else -> 0
}
}
Тем не менее, это (на мой взгляд) выглядит ужасно, когда количество классов увеличивается, скажем, от 3-4 до 40+. Я думал о том, чтобы сделать что-то вроде псевдокода ниже:
// store all the possible types in a list
val typesThatShouldReturn1 = listOf<BaseType>(
// TODO: figure out how to store types in a list without instantiating
)
fun processObject(obj: BaseType): Int {
if (typesThatShouldReturn1.any { obj is it }) {
return 1
}
return 0
}
Возможно ли это даже в котлине?
Re: некоторые комментарии.
Почему я не использую интерфейс маркера? Поскольку эта функция processEvent
будет реализована во многих различных контекстах, и введение интерфейса маркера для каждого из них не является хорошим решением. Кроме того, классы baseType
являются частью системы CQRS, где в идеале наша логика записи не должна касаться нашей логики чтения. Это самая большая причина, по которой интерфейс маркера мне здесь не подходит.
Почему BaseType
не реализует эту логику? См. Комментарий выше о том, что processEvents
реализуется по-разному в разных контекстах. Кроме того, базовый тип не имеет проблемы с логикой чтения, поэтому он никогда не должен реализовывать это.
listOf(A::class, B::class, C::class, ...)
выглядит лучше, чем is A, is B, is C, ...
? Это выглядит более или менее одинаково.
Действительная точка. Это более личное предпочтение, так как я не возражаю против private val typesThatShouldReturn1
почти столько же.