假设我有两个配置对象,每个配置对象都包含通过“Test”和“prod”模式运行Scala程序的参数:
object Test = {
param1 = "test"
}
object Prod = {
param1 = "test"
}
是否有正确的方法来确定哪个Config应该用作运行程序的一部分?
虽然我认为这是非常不干净的一种可能的方法是根据确定运行模式的其他var参数为有问题的var分配一个新的var。所以:
object Mode = {
val mode = "Prod"
}
然后当需要参数时:
Object useParam = {
var param1;
if(Mode.mode.equals("Prod")
param1 = Prod.param1
else
param1 = Test.param1
}
答案 0 :(得分:0)
尝试尽可能贴近您的初始代码,您可以让 config 对象使用所有变量的方法实现特征,并使此配置类型为mode
,像这样:
trait Config {
def param1: String
}
object Test extends Config {
val param1 = "test"
}
object Prod extends Config {
val param1 = "test"
}
object Mode {
val mode: Config = Prod
}
object UseParam {
Mode.mode.param1
}
或者你可以使用依赖注入并在你的类中注入一个Config
实例,如下所示:
class UseParam(config: Config) {
config.param1
}
在这种情况下,您必须在实例化此类时传递正确的Config
实现(Prod
或Test
)。
答案 1 :(得分:0)
简单的事情:
// need a common base type for ProdSettings and TestSettings
// so they could be stored in the same constant
trait Settings {
def param1: String
def param2: Int
}
object ProdSettings extends Settings {
val param1 = "foo"
val param2 = 123
}
object TestSettings extends Settings {
val param1 = "bar"
val param2 = 456
}
// no need to wrap the attribute in `object Mode`
// as you can have top-level constants in Scala
val Mode = 'production
// don't use a var for this
val Conf = if (Mode == 'production) ProdSettings else TestSettings
println(s"param1: ${Conf.param1}")
println(s"param2: ${Conf.param2}")
另请注意,通常会避免使用var
,而Scala中不需要if
;在定义val
时,您始终可以直接使用implicit val Conf = if (Mode == Production) ProdSettings else TestSettings
def configConsumer(arg1: Int, arg2: Double)(implicit conf: Settings) = {
println(arg1 * arg2 * conf.param2)
}
// globally enabled configuration used implicitly
configConsumer(1, 2.3)
// custom MockSettings
configConsumer(1, 2.3)(new Settings { val param1 = "baz"; val param2 = 789 })
。
但是,我不是直接引用模块,而是单独传递各个配置项,以保持良好和干净。
如果您仍然希望继续引用整个配置,我宁愿使用implicits而不是依赖注入,这使得可以选择将配置对象传递给一段逻辑,但如果没有指定,则可以回退到默认值。 :
{{1}}