在软件开发中,我们常常为沟通效率低下而头疼。
接手维护项目时,面对低质量代码,不得不一次又一次地与前任开发者沟通;
团队内部,模块分散,编程风格各异,使用对方服务时需要反复确认;
跨团队合作,技术栈不同,更需要花费大量时间统一标准……
这些问题的根源在于代码本身带来的学习成本和沟通成本。每一份代码都像是一本需要重新学习的书籍,需要反复研究和沟通才能理解。
然而,为什么学习了 Spring 框架后,我们与他人交流相关问题时效率会显著提高?
答案在于 Spring Boot 框架应用了一个简单却强大的原则:惯例优于配置(Convention over Configuration,CoC)。
这个原则帮助编程者提前建立起隐形的公共知识体系,当一方提及某个知识点时,另一方早已心领神会,无需反复解释,沟通效率自然水到渠成。
一、惯例原则:用“共同语言”编程
惯例原则起源于 Ruby On Rails 框架,其核心理念是将编程中公认的配置方式和约定信息作为内部默认规则。例如MyBatis 的映射文件通常命名为 xxxMapper.xml。
由于是默认统一的规则,大多数开发者都会优先采用,久而久之,便对规则形成统一认知,沟通时自然减少了重复理解和沟通的时间。
我们可以将惯例原则理解为一种约束,在特定框架(知识体系)下,根据这些约束制定默认规则,框架便能基于这些规则实现统一操作。
例如,Spring 框架中,使用 @Autowired 注解自动注入 Java Bean,框架通过解析注解自动寻找对应的 Bean。
因此,惯例原则也被称为“按约定编程”。
与契约原则(DBC)强调的“按统一协议/标准协作”不同,惯例原则更注重隐性知识的共享。
例如,使用 Maven 管理工程结构,其实是预设了维护者已经了解 Maven 相关的惯例约定。
二、惯例原则解决的问题
以常见的 Maven 自动生成的 Java 工程结构为例,这个目录结构对 Java 程序员来说不言自明,这就是一种公认的惯例。
惯例原则主要解决了编程中对共同隐性知识的学习问题,通过统一的默认规则,建立起沟通的桥梁。
当然,我们可以不使用惯例,但代价是花费大量时间解释和说明新规则,并确保消除其他人的误解。
除此之外,惯例原则还间接带来了以下好处:
● 形成编程圈的专业行话
在编程领域,使用惯例就像使用专业术语,无需额外解释, everyone gets it.
● 减少决策次数,降低认知负担
惯例帮助开发者快速做出选择,避免在众多技术方案中犹豫不决,从而专注于解决实际问题。
三、惯例原则的副作用
使用惯例原则能带来良好的可维护性和沟通效率,但也要警惕其潜在的副作用:
● 灵活性降低
过于定制化的默认规则,虽然统一了认知,但也限制了灵活性。例如,统一使用 ApiResponseResult 类处理 JSON 返回格式,如果需要修改数据格式,可能需要改动大量代码。
● 自定义惯例的风险
自定义惯例需要团队内部反复确认,否则可能导致严重问题。例如,数据库 YN 字段默认值不统一,可能导致数据迁移时出现错误。
● 参考变强制
惯例原则可能演变成强制标准,导致设计僵化。例如,数据类只能写 get、set 方法,或者代码只写在一个层级。
● 不同框架惯例不可复用
不同知识体系下的惯例不同,不可混淆使用。例如,C++ 和 Java 的开发惯例就存在差异。
四、如何正确使用惯例原则
为了避免惯例原则的副作用,我们需要掌握以下技巧:
● 遵循大多数人的惯例
选择业界公认的惯例,例如 Java 的驼峰命名、MySQL 数据库字段的下划线分割等,确保理解一致性,减少沟通成本。
● 明确惯例的适用范围
不同的惯例适用于不同的编程语言、场景和行业,需要根据实际情况选择使用。
● 自定义惯例需团队确认
自定义惯例时,确保团队内每个人都知晓并理解,并在实际编码中与调用方反复确认。
● 平衡惯例与灵活性
不要过度使用惯例,在需要灵活性的情况下,可以选择配置或代码实现。
● 避免强制他人使用惯例
惯例应该是一种自由选择,而不是强制要求,避免破坏他人的编程习惯,降低开发效率。
总之,惯例优于配置原则就像软件开发中的隐形桥梁,帮助我们跨越沟通的鸿沟,提升开发效率。
但也要警惕其潜在的副作用,灵活运用,才能最大限度地发挥其优势,构建高效、可维护的优质软件。