samedi 19 novembre 2022

How to structure an interdependent domain with Kotlin classes and functions

Me and my team are refactoring/rewriting a legacy Java library which basically contains our domain model. We're doing it to modernize our applications and reduce the amount of bugs that a developer can make while using this library due to the 'open' APIs it has in the legacy version.

The problem we're facing is that our domain is quite complex and a lot of its concepts are interdependent with each other.

As an example we've a set of enums that intrinsically depend on each other, something like this:

enum class Type {
    A, B, C, D
}

enum class Model {
    X, Y, Z
}

enum class Frequency {
    FREQUENCY_100,
    FREQUENCY_200,
    FREQUENCY_300,
    FREQUENCY_400,
    FREQUENCY_500,
    FREQUENCY_600,
    FREQUENCY_700
}

data class Status(
    val type: Type,
    val model: Model,
    val frequency: Frequency
) {
    init {
        // validation code
    }
}

The problem is that we've a lot of constraints about which Frequency values are valid depending on the values of Type and Model. For instance, for types A and B, with models X and Y, the frequencies below 500 are available; for types A only, with models Y and Z, the frequencies above 500 are available; and so on. This is not really the real situation, but it illustrates the problem.

I've read about functional domain modeling, some articles about Kotlin lambda functions with receivers and the new experimental feature of context receivers and was thinking if something like this would be possible:

val status = status(type, model) {
    frequency = // only available frequencies checked by the compiler
}

To wrap things up, frequency is just one of the interdependent variables. We've more cases like this and this domain is constantly evolving as the product grows. Any ideas or design principles that I could apply to this case?

Aucun commentaire:

Enregistrer un commentaire