Tengo las siguientes clases:
sealed class A : BaseType sealed class B : BaseType sealed class C : BaseType ... Si luego tengo un método processObject que se ve así:
fun processObject(obj: BaseType): Int { return when(obj) { is A -> 1 is B -> 1 else -> 0 } }Me doy cuenta de que ahora me estoy repitiendo, así que podría cambiar ese método a algo como esto:
fun processObject(obj: BaseType): Int { return when(obj) { is A, is B -> 1 else -> 0 } }Sin embargo, esto (en mi opinión) se ve muy feo cuando el número de clases va de, digamos, 3-4 a más de 40. Estaba pensando en hacer algo en la línea del pseudocódigo a continuación:
// 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 }¿Es esto posible en kotlin?
Re: algunos comentarios.
¿Por qué no estoy usando una interfaz de marcador? Debido a que esta función processEvent se implementará en muchos contextos diferentes, la introducción de una interfaz de marcador para todos y cada uno de ellos no es una buena solución. Además, las clases baseType son parte de un sistema CQRS en el que, idealmente, nuestra lógica de escritura no debería preocuparse por nuestra lógica de lectura. Esta es la principal razón por la que una interfaz de marcador no es viable para mí aquí.
¿Por qué BaseType no implementa esta lógica? Consulte el comentario anterior sobre la implementación de processEvents de diferentes maneras en diferentes contextos. Además, el tipo base no tiene la lógica de lectura como una preocupación, por eso nunca debería implementar esto.
¿ listOf(A::class, B::class, C::class, ...) se ve mejor que is A, is B, is C, ... ? Se ve más o menos igual. Punto valido. Esta es una preferencia más personal, ya que no me importa un private val typesThatShouldReturn1 casi tanto.
Claro, puedes escribir algo como esto.
val typesThatShouldReturn1 = listOf( A::class ) fun processObject(obj: BaseType): Int { if (typesThatShouldReturn1.any { it.isInstance(obj) }) { return 1 } return 0 }Su ejemplo no está claro, pero parece que estaba tratando de hacer esto:
sealed class BaseType class A : BaseType class B : BaseType class C : BaseType (lo que significa que BaseType solo puede ser uno de A , B o C ; esto es consistente con el uso deseado de when )
Lo que está diciendo efectivamente es que A y B son fundamentalmente similares y deben manejarse de la misma manera. Suponiendo que A y B realmente necesitan ser clases separadas, una solución es que comparten una superclase común que en realidad no es BaseType :
sealed class BaseType open class ABCommon : BaseType class C : BaseType class A : ABCommon class B : ABCommon fun processObject(obj: BaseType): Int { return when(obj) { is ABCommon -> 1 else -> 0 } }