我有一个使用从.conf文件读取的数据a
创建的类。该类还包含一个值b
,该值不是来自conf文件。
课程:
case class Configuration(a: String, b: String)
实例化配置的调用顺序如下:
用户-> ConfigurationCompiler
-> ConfigurationReader
-> readConfig(): Configuration
(用户返回一个Configuration对象)
值a
由.conf文件读取和设置,但值b
由用户指定。我不想一直将值b
传递给readConfig(),因此可以在Configuration
的实例化时进行设置。
我已经尝试过Option
,但对我来说看起来很丑陋,因为您首先使用b
实例化了None
,然后再进行设置。另外,测试看起来很奇怪,因为您必须测试Some(String)
而不是String
。选项似乎也不适合这里,因为该字段实际上不是 可选的,只是在以后设置。
Option
类:
case class Configuration(a: String, var b: Option[String])
答案 0 :(得分:1)
我会去买builder
。这是一个示例:
import cats.implicits._
import cats.data.ValidatedNel
case class ConfigBuilder(a: Option[String] = None, b: Option[String] = None) {
def withA(a: String): ConfigBuilder = copy(a = Some(a))
def withB(b: String): ConfigBuilder = copy(b = Some(b))
def build: ValidatedNel[String, Configuration] =
(a.toValidNel("'a' must be defined"), b.toValidNel("'b' must be defined"))
.mapN(Configuration)
}
验证两个字段:
ConfigurationBuilder()
.build
// Invalid(NonEmptyList('a' must be defined, 'b' must be defined))
获得有效的配置:
ConfigurationBuilder()
.withA("test")
.withB("test2")
.build
// Valid(Configuration(test,test2))
答案 1 :(得分:0)
某些解决方案可能是使用NULL
,但implicit
看起来并不好-隐式类型是按类型解析的,因此应该比implicit String
通用。 >
我能想到的是String
返回的PartialConfiguration
之类的东西。然后,可以将其值添加到readConfig()
提供的值中以创建完整的User
。
答案 2 :(得分:0)
您可以使用b
位置中的默认值创建原始配置对象。当您获得b
的实际值时,请使用以下程序创建程序使用的副本:
val realConfig = originalConfig.copy( b = bValue )
副本将b
字段替换为实际使用所需的值。