刚开始做数据源接入时,我很喜欢加配置项。
连接地址不一样,加一个;认证方式不一样,再加一个;某个客户的字段需要特殊处理,再加一个开关。配置看起来比改代码优雅,也比复制一套服务克制。
但配置并不是免费的抽象。每增加一个布尔值,系统理论上就多出两种状态;两个布尔值是四种,十个相互独立的开关则可能组合出 1024 种行为。实际上不会有人测试完这些组合,最后只能依赖“我们线上一般这样配”的经验。
三类配置
后来我会先判断它属于哪一类。
环境差异,例如地址、端口、证书路径,适合留在配置里。
业务策略,例如重试次数、采集周期、数据保留时间,也可以配置,但要有边界、默认值和可观测性。
程序分支,例如 special_customer_mode=true,通常是在借配置逃避建模。它今天只是一个判断,半年后会渗入查询、缓存、日志和升级脚本。
我给自己留了一个简单问题:
删除这个配置项时,需要修改多少处代码?
如果答案是“几乎所有模块”,它就早已不是配置,而是一条没有名字的架构边界。
好的配置让同一套能力适应不同环境;坏的配置则让几套不同的系统勉强住在同一个仓库里。