I have an immutable configuration class, which can be only changed by constructing a copy of it using copy() call. The main for its construction is all good, but I also have an auxiliary flow, where configuration after construction can be modified based on a collection of modifiers.
This results in a following code:
def updateConfigUsingMods(config: Config, mods: Modifiers): Config = {
val config1 = if (mods.mod1) {
config.copy(param1 = false, param2 = true)
} else {
config
}
val config2 = meta.mod2 match {
case Some(value) => config1.copy(param3 = value)
case None => config1
}
val config3 = meta.mod3 match {
case Some(value) => config2.copy(param4 = value)
case None => config2
}
// etc
config3
}
This chain of updates looks ugly and is incredibly error prone. The only other way I can think of is reserving responsibility and make Modifiers do the updates, but this looks ugly and overly verbose to my taste too:
case class Modifiers(mod1: Boolean, mod2: Option[Boolean], mod3: Option[String] {
def updateConfigForMod1(config: Config): Config =
if (mod1) {
config.copy(param1 = false, param2 = true)
} else {
config
}
def updateConfigForMod2(config: Config): Config =
mod2 match {
case Some(value) => config.copy(param3 = value)
case None => config
}
def updateConfigForMod3(config: Config): Config =
mod3 match {
case Some(value) => config.copy(param4 = value)
case None => config
}
def updateConfig(config: Config): Config =
updateConfigForMod1(config).updateConfigForMod2(config).updateConfigForMod3(config)
}
Is there a better way to achieve this?