Convention over Configuration over Programming
什么是 Convention over Configuration over Programming
在软件工程中,有一条重要的设计哲学层级:
Convention over Configuration over Programming
约定优于配置,配置优于编程。
这条原则的核心思想是:能用约定解决的问题,就不要引入配置;能用配置解决的问题,就不要写代码。 它反映了软件设计中对复杂度管理的追求——越是高层次的抽象,使用成本越低,出错概率也越小。
三个层次的含义
Programming(编程)
编程是最灵活但成本最高的方式。开发者需要编写具体的代码逻辑来实现功能。每一行代码都是潜在的 bug 来源,都需要测试、维护和 review。编程适合处理那些真正需要定制化逻辑的场景。
Configuration(配置)
配置是介于约定和编程之间的中间层。通过外部化的配置文件(如 XML、YAML、properties 等),开发者可以在不修改代码的情况下改变程序行为。配置降低了修改成本,但引入了配置管理的复杂度——配置项越多,理解和维护系统的难度就越大。
Convention(约定)
约定是成本最低的方式。通过预先定义好的规则和默认行为,开发者只需要遵循约定就能让系统正常工作。约定减少了决策负担,让团队成员能够快速理解和上手项目。
经典案例
Ruby on Rails 是 “Convention over Configuration” 理念的经典实践者。在 Rails 中:
- 模型类
User自动映射到数据库表users,无需配置 ORM 映射 - 控制器
UsersController自动对应路由/users,无需手动注册路由 - 视图文件放在
app/views/users/目录下,框架自动查找渲染
Spring Boot 同样深谙此道:
- 引入
spring-boot-starter-web依赖,自动配置嵌入式 Tomcat、Spring MVC 等组件 - 配置文件放在
src/main/resources/application.yml,框架自动加载 @SpringBootApplication注解自动开启组件扫描、自动配置等功能
Maven 的标准目录结构也是约定的体现:
src/main/java放主代码,src/test/java放测试代码src/main/resources放资源文件- 遵循约定就无需在 POM 中显式配置源码目录
配置的优先级
在配置层面,通常存在一个优先级链:
命令行参数(cmd args) > 环境变量(env) > 配置文件(configuration file)
这个优先级设计背后的逻辑是:越临时、越具体的配置,优先级越高。
- 命令行参数:最高优先级,适合一次性的临时覆盖,如调试时指定端口号
- 环境变量:中等优先级,适合区分不同部署环境(开发、测试、生产),也是 12-Factor App 推荐的配置方式
- 配置文件:最低优先级,承载默认配置和基础设定,是系统行为的"基线"
Spring Boot 的配置加载顺序完美体现了这一原则:命令行参数 > SPRING_APPLICATION_JSON > 系统环境变量 > application-{profile}.yml > application.yml。
命令行中的 Option、Argument 与 Flag
理解命令行工具的参数模型,也有助于理解配置的本质。一条命令的结构可以类比为自然语言的句子:
1 | |
- Command(命令):告诉程序做什么(what to do),相当于句子中的动词
- Argument(参数):命令的操作对象,相当于句子中的宾语(名词或代词)
- Option / Flag(选项/标志):影响程序怎么做(how to do),相当于句子中的副词或形容词。Option 是可选参数,Flag 通常是布尔形态的 Option
举几个例子:
1 | |
这个模型揭示了一个有趣的对应关系:Argument 定义了配置的"是什么",而 Option/Flag 定义了配置的"怎么样"——这与 Convention-Configuration-Programming 的层次思想一脉相承。
设计启示
这条原则对日常开发有几点实用启示:
- 设计框架或库时,应该提供合理的默认值(sensible defaults),让用户零配置即可上手,同时保留配置扩展点
- 设计配置体系时,应该遵循分层覆盖的优先级模型,让不同粒度的配置各司其职
- 做技术选型时,优先选择约定清晰、配置简洁的方案,避免过度配置带来的"配置地狱"(configuration hell)
- 编写代码时,如果发现某段逻辑可以被约定或配置替代,就应该考虑将其提升到更高的抽象层次





