I am trying to implement a Role class/interface/enum that I can use throughout my program. I want the roles to be somewhat categorized - I want some roles to be of type A, some roles to be of type B, and some roles to be part of multiple types. I want to be able to know all the roles from each type - so an enum/sealed class structure is the idea. I tried the following implementation -
sealed interface UserRole {
val roleName: String
}
enum class RoleA(override val roleName: String): UserRole {
A(roleName = "A"),
B(roleName = "B"),
C(roleName = "C"),
D(roleName = "D");
companion object {
fun fromRoleName(roleName: String): RoleA? =
values().singleOrNull { it.roleName == roleName }
}
}
enum class RoleB(override val roleName: String, val secondParam: String): UserRole {
A(roleName = "A", secondParam = "A"),
E(roleName = "E", secondParam = "E"),
F(roleName = "F", secondParam = "F");
companion object {
fun fromRoleName(roleName: String): RoleB? =
values().singleOrNull { it.roleName == roleName }
}
}
As you can see, A is part of both enums, but I would ideally want them to be the same object. Likewise I want to have the ability to create more of these enums in the future in case I need more types of roles.
Before I tried sealed interfaces, I simply had 1 big enum called UserRole that simply had all the values, and I used another class called RoleType and a simple mapping between the two to get what I wanted, but I don't think it does exactly what I want. Can anyone suggest a better way to categorize enum values?
You could reflect your roles in the type system by defining a sealed interface for each role type like this:
sealed interface Type1 {
val t: Int
fun test()
}
sealed interface Type2 {
val s: String
}
Then your Role
class could be defined as a sealed class
and every class could implement your Role types as fit.
sealed class Role
class A(override val t: Int, override val s: String) : Role(), Type1, Type2 {
override fun test() {
print("hello")
}
}
class B(override val s: String) : Role(), Type2
This does bring some overhead in the amount of code necessary to define each Role, so be aware of this when weighing pros and cons of each variant.