我一直在考虑配置文件及其与代码的关系一段时间了,根据风的日期和方向,我的意见似乎发生了变化.虽然我不断回过头来学习Lisp时的第一次实现:数据和代码之间几乎没有什么区别.对配置文件来说,这似乎是双重的.从正确的角度来看,Perl脚本只不过是perl的配置文件.这往往会对QA和分工等任务造成相当严重的后果,例如谁应该负责更改配置文件.
从配置文件到完全成熟的语言的蠕变通常很慢,似乎是由拥有通用系统的愿望驱动的.大多数项目似乎从一些配置项开始很小,比如在哪里写日志,在哪里查找数据,用户名和密码等等.但随后它们开始增长:功能开始能够打开或关闭,操作的时间和顺序开始被控制,并且,不可避免地,有人想要开始向其添加逻辑(例如,如果机器是X则使用10,如果机器是Y则使用15).在某个时刻,配置文件成为特定于域的语言,并且在那时写得很差.
现在我已经漫步到舞台上,这是我的问题:
配置文件的真正目的是什么?
是否应该尝试保持配置文件简单?
谁应该负责对它们进行更改(开发人员,用户,管理员等)?
它们应该是源控制的吗(参见问题3)?
正如我之前所说,我对这些问题的回答不断变化,但现在我在想:
允许非程序员快速更改大块行为
是的,任何非粗粒度的东西都应该是代码
用户应负责配置文件,程序员应负责配置文件和代码之间的配置层,以便对应用程序进行更精细的控制
不,但细粒度的中间层应该是
MiniQuark.. 39
非常有趣的问题!
我倾向于将我的配置文件限制为一个非常简单的"key = value"格式,因为我完全同意你的配置文件可以很快成为完整的程序.例如,任何试图"配置"OpenSER的人都知道你在谈论的感觉:它不是配置,而是(痛苦的)编程.
如果您需要以当前无法想象的方式使应用程序具有"可配置性",那么您真正需要的是插件系统.您需要以其他人可以编写新插件的方式开发您的应用程序,并在将来将其挂钩到您的应用程序中.
那么,回答你的问题:
配置文件的真正目的是什么?
我想说,允许安装应用程序的人能够调整一些与部署相关的参数,例如主机名,线程数,所需插件的名称以及这些插件的部署参数(检查出FreeRadius的配置为这个原理的一个例子)等等.绝对不是表达业务逻辑的地方.
是否应该尝试保持配置文件简单?
当然.正如您所说,配置文件中的"编程"非常糟糕.我认为应该避免.
谁应该负责对它们进行更改(开发人员,用户,管理员等)?
一般来说,我会说部署应用程序的管理员.
它们应该是源控制的吗(参见问题3)?
我通常不对源配置文件本身进行源代码控制,但是我使用所有参数及其默认值来源控制模板配置文件,并使用注释来描述它们的作用.例如,如果命名了配置文件database.conf
,我通常会对名为的文件进行源代码控制database.conf.template
.当然,我正在谈论我作为开发人员所做的事情. 作为管理员,我可能希望源代码控制我为每个安装选择的实际设置.例如,我们远程管理几百台服务器,我们需要跟踪它们的配置:我们选择使用源代码控制来执行此操作.
编辑:虽然我认为上述情况适用于大多数应用程序,但当然总有例外.例如,您的应用程序可能允许其用户动态配置复杂规则.大多数电子邮件客户端允许用户定义用于管理其电子邮件的规则(例如,"来自'john doe'的所有电子邮件并且不会让我在To:字段中被丢弃").另一个例子是允许用户定义新的复杂商业报价的应用程序.您还可以考虑像Cognos这样的应用程序,它们允许用户构建复杂的数据库报告.电子邮件客户端可能会为用户提供一个简单的界面来定义规则,这将生成一个复杂的配置文件(甚至可能是一些代码).另一方面,商业报价的用户定义配置可以以结构化方式保存在数据库中(既不是简单的键=值结构也不是代码的一部分).而其他一些应用程序甚至可能允许用户使用python或VB或其他一些支持自动化的语言进行编码.换句话说......你的里程可能会有所不同.
非常有趣的问题!
我倾向于将我的配置文件限制为一个非常简单的"key = value"格式,因为我完全同意你的配置文件可以很快成为完整的程序.例如,任何试图"配置"OpenSER的人都知道你在谈论的感觉:它不是配置,而是(痛苦的)编程.
如果您需要以当前无法想象的方式使应用程序具有"可配置性",那么您真正需要的是插件系统.您需要以其他人可以编写新插件的方式开发您的应用程序,并在将来将其挂钩到您的应用程序中.
那么,回答你的问题:
配置文件的真正目的是什么?
我想说,允许安装应用程序的人能够调整一些与部署相关的参数,例如主机名,线程数,所需插件的名称以及这些插件的部署参数(检查出FreeRadius的配置为这个原理的一个例子)等等.绝对不是表达业务逻辑的地方.
是否应该尝试保持配置文件简单?
当然.正如您所说,配置文件中的"编程"非常糟糕.我认为应该避免.
谁应该负责对它们进行更改(开发人员,用户,管理员等)?
一般来说,我会说部署应用程序的管理员.
它们应该是源控制的吗(参见问题3)?
我通常不对源配置文件本身进行源代码控制,但是我使用所有参数及其默认值来源控制模板配置文件,并使用注释来描述它们的作用.例如,如果命名了配置文件database.conf
,我通常会对名为的文件进行源代码控制database.conf.template
.当然,我正在谈论我作为开发人员所做的事情. 作为管理员,我可能希望源代码控制我为每个安装选择的实际设置.例如,我们远程管理几百台服务器,我们需要跟踪它们的配置:我们选择使用源代码控制来执行此操作.
编辑:虽然我认为上述情况适用于大多数应用程序,但当然总有例外.例如,您的应用程序可能允许其用户动态配置复杂规则.大多数电子邮件客户端允许用户定义用于管理其电子邮件的规则(例如,"来自'john doe'的所有电子邮件并且不会让我在To:字段中被丢弃").另一个例子是允许用户定义新的复杂商业报价的应用程序.您还可以考虑像Cognos这样的应用程序,它们允许用户构建复杂的数据库报告.电子邮件客户端可能会为用户提供一个简单的界面来定义规则,这将生成一个复杂的配置文件(甚至可能是一些代码).另一方面,商业报价的用户定义配置可以以结构化方式保存在数据库中(既不是简单的键=值结构也不是代码的一部分).而其他一些应用程序甚至可能允许用户使用python或VB或其他一些支持自动化的语言进行编码.换句话说......你的里程可能会有所不同.
好.你会有一些想要一个非常简单的配置的用户,你应该给它们.与此同时,你会不断要求"你能添加这个吗?我怎么做配置文件?",我不明白为什么你不能支持这两个组.
我目前正在处理的项目使用Lua作为其配置文件.Lua是一种脚本语言,它在这种情况下运行良好.有一个默认配置示例.
你会注意到它主要是key = value语句,其中value可以是Lua的任何内置类型.最复杂的是列表,它们并不是很复杂(只是语法问题).
现在我只是在等待有人询问如何在每次启动时将服务器的端口设置为随机值...
最近我正在研究一个项目,我意识到我想在我的配置文件中包含条件 - 以前只是一个非常简单的形式:
key = val
key2 = val
name = `hostname`
我不想写一种迷你语言,因为除非我非常谨慎地做到这一点,否则我不能允许有用的灵活性.
相反,我决定我有两种形式:
如果文件以"#!"开头 并且是可执行的我将解析运行它的结果.
否则我会按原样阅读
这意味着我现在可以允许人们编写如下所示的"配置文件":
这样,如果用户想要使用它,我就可以获得动态配置文件的强大功能,而且不必编写我自己的迷你语言.
#!/usr/bin/perl
if ( -x /bin/foo )
{
print <