在之前的文章《设计杂谈(0x01)——配置文件的起源与矛盾》中,笔者对配置文件的起源,以及存在的矛盾进行了探讨。而在这一系列的第二篇中,将对上述矛盾提供进一步的分析,并尝试通过引入“约定大于配置”的设计思想来解决这一问题。
话不多说,开始。
约定大于配置
对于提升配置文件系统的易用性和可操作性,笔者认为其中一种较好的优化思路是 “约定大于配置”(Convention over Configuration,简称为CoC),一般采用如下的定义(见Convention over configuration - Wikipedia)
Convention over configuration (also known as coding by convention) is a software design paradigm used by software frameworks that attempts to decrease the number of decisions that a developer using the framework is required to make without necessarily losing flexibility and don’t repeat yourself (DRY) principles.
简单来说,就是如下几点:
- 约定一个具备明确实际意义的【常规态】
- 对【常规态】要有完整的描述,并将其作为默认值
- 撰写配置时,只需要写明“非常规”的部分,剩下的部分交给【常规态】
- 这样的方式可以极大减少撰写配置时的决策与重复,满足“不要自我重复(Don’t Repeat Yourself,简称DRY)”的设计原则
而这其中最为关键的,则是要去设定一个“常规态”。出于方便易用、表意清晰的考虑,需要对实际代码逻辑的最常用形态有足够的了解,才能定义和抽象出所谓的“常规态”。并且,为了支持更多定制化的功能,也应该提供一系列的附加配置。同时,附加配置依然需要基于“常规态”赋予其默认值,以简化使用。换句话说,不要让复杂的需求影响最常用的体验,也不要让编写者进行一系列重复且不必要的选择。
例如,对于写过Java代码的开发者而言,如果使用了Maven框架创建项目的话,一般将会呈现如下图所示的项目结构:
(基于Maven的Java项目结构,源码、单元测试、编译产物、项目配置均在固定的位置)
你可能会疑惑——为什么一定要组织成这样呢?或者说,是否可以换个方式来组织(比如源代码目录改作 code
,或者编译产物目录改作 build
等),并且一样可以正常地编译、运行与测试呢?答案其实很简单——并不一定非要这样。实际上,具体的组织形式,例如项目结构、各个文件/目录的命名等,都是可以修改的。然而,在实际使用的情况下,这样的修改并无必要性,作为代码的编写者,只需要按照这样一个既定的模式来编写项目代码即可解决上述全部问题,那么当然就没有手动进行额外配置的必要了。而针对极端特殊的情况,只需要在项目配置中进行少量的修改,一样可以达成所需的效果。
这样隐含的“约定”,实际上广泛存在于各种语言的各种框架中,其中在Web应用框架中尤其普遍存在。例如,将约定大于配置设计原则发挥到极致的Ruby on Rails框架中,数据模型部分在“关系”(即数据表之间的关系,例如一对一的“has one”,一对多的“has many”,代表从属的“belong to”等,这在数据库与数据模型的设计中极为常见)上的设计就极好的遵循了这一原则。下面就让让我们来看一看其中 has_many
,也就是一对多关系具体的参数设计(原地址)
(has_many的部分参数及使用说明,全部参数共计18个)<