如何实施配置和设置?

发布于 2024-10-15 17:52:32 字数 511 浏览 2 评论 0原文

我正在编写一个部署在多个地方的系统,每个站点都需要自己的配置和设置。 “配置”是特定站点必需的命名值(例如数据库 URL、S3 存储桶名称);每个配置都是必要的,通常没有默认值,并且通常是字符串值。设置是一个命名值,但它只是调整系统的行为;它通常是数字或布尔值,并且通常有一些默认值。

到目前为止,我一直在使用属性文件或类似的东西,但这是一个糟糕的解决方案。有几次,开发人员添加了配置要求,但没有将值添加到实时配置文件中,因此新版本通过了所有测试,但在发布时却失败了。

当然,更好的是,对于要编译的每个文件(因此,如果缺少配置或其中一种类型错误,它将无法通过编译器)并将特定于站点的类注入到每个站点的构建中。作为骨骼,Scala 文件可以轻松地对更复杂的值进行建模,尤其是列表,还可以对映射和元组进行建模。

缺点是,这些文件有时是由非开发人员维护的,因此它必须非常不言自明,这是属性文件的优点。 (有人向我解释 XML 配置:可编译文件的所有复杂性,但属性文件的运行时风险。)

我正在寻找的是一种定义组所需名称和允许值的简单模式。有什么建议吗?

I'm writing a system that is deployed in several places and each site needs its own configurations and settings. A "configuration" is a named value that is necessary to a particular site (e.g., the database URL, S3 bucket name); every configuration is necessary, there is not usually a default, and it's typically string-valued. A setting is a named value but it just tweaks the behavior of the system; it's often numeric or Boolean, and there's usually some default.

So far, I've been using property files or thing like them, but it's a terrible solution. Several times, a developer has added a requirement for a configuration but not added the value to file for the live configuration, so the new release passed all the tests, then failed when released to live.

Better, of course, for every file to be compiled — so if there's a missing configuration, or one of the wrong type, it won't get past the compiler — and inject the site-specific class into the build for each site. As a bones, a Scala file can easy model more complex values, especially lists, but also maps and tuples.

The downside is, the files are sometimes maintained by people who aren't developers, so it has to be pretty self-explanatory, which was the advantage of property files. (Someone explain XML configurations to me: all the complexity of a compilable file but the run-time risk of a property file.)

What I'm looking for is an easy pattern for defining a group required names and allowable values. Any suggestions?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

只有一腔孤勇 2024-10-22 17:52:32

使用 Mixin 组合怎么样?由于特征是从右到左应用的,我们可以:

定义特征:

默认属性:

trait PropertyA {   
   val userName = "default"
   def useUserName() : Unit = {
     println(userName)
   }
}

一些其他属性:

trait SomePropertyA extends PropertyA {   
   val userName = "non-default"
   def useUserName() : Unit = {
     println(userName)
   }
}

定义具有默认属性的抽象类:

trait HasPropertyA {
   val prop : PropertyA = new PropertyA
}

定义具有非默认属性的抽象类:

trait HasSomeOtherPropertyA extends HasPropertyA {
       override val prop:PropertyA   = new SomePropertyA {}
}

在您的类中使用默认属性:

trait MyClass extends PropertyA {
   doSomethingWith(prop.userName)
}

或在另一个中将其与其他属性混合的情况:

if(env.isSome) {
   val otherProps = MyClass with HasSomeOtherPropertyA
   doSomethingWith(prop.userName)// userName == non-default! 
}

请阅读论文 Scalable Component Abstractions

How about using Mixin composition? Since traits are applied from right to left we can:

Define traits:

default property:

trait PropertyA {   
   val userName = "default"
   def useUserName() : Unit = {
     println(userName)
   }
}

some other property:

trait SomePropertyA extends PropertyA {   
   val userName = "non-default"
   def useUserName() : Unit = {
     println(userName)
   }
}

Define an abstract class with default property:

trait HasPropertyA {
   val prop : PropertyA = new PropertyA
}

Define an abstract class with non - default property:

trait HasSomeOtherPropertyA extends HasPropertyA {
       override val prop:PropertyA   = new SomePropertyA {}
}

In your class use default one:

trait MyClass extends PropertyA {
   doSomethingWith(prop.userName)
}

or in the other situation mix it with some other property:

if(env.isSome) {
   val otherProps = MyClass with HasSomeOtherPropertyA
   doSomethingWith(prop.userName)// userName == non-default! 
}

Read in more detail in the paper Scalable Component Abstractions

我为君王 2024-10-22 17:52:32

虽然 Lift 本质上是一个 Web 框架,但它也有一些实用程序。其中之一是依赖注入,请参阅:http://simply.liftweb。 net/index-8.2.html#toc-Section-8.2。因此,您可以使用默认值创建一个基本trait,然后对运行时、开发、测试...环境值进行子类化。我认为对于不了解 scala 的人来说,很容易在文件中放置一些 override def defaultValue = "new value"

Although Lift is a web framework in its essence, it has some utilities as well. One of them is Dependency Injection, see : http://simply.liftweb.net/index-8.2.html#toc-Section-8.2. So you can for example create a base trait with default values and then subclass the Runtime, Development, Test... environment values. And I think that it's easy for someone without knowledge of scala to put some override def defaultValue = "new value" in a file.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文