当我开始为系统长期演进负责之后
过去的一年里,我参与并主导了多个不同阶段的项目: 重构已经积累大量历史负担的老系统,也从 idea 开始,独立推进过项目的立项、架构设计、研发与上线,同时还在多个团队之间进行深度协作。
是在这些实践中,我逐渐意识到,很多工程问题并不是“技术能力不足”,而是对接口、边界以及变化的理解存在偏差。
当你需要为系统的长期演进负责,而不只是完成一次性交付时,接口不再只是 HTTP 入口,而是变成真正的协作契约;模块不再只是代码集合,而会逐渐呈现出“作品”的形态。
这篇文章,正是基于这一年真实工程实践中的反思与总结,尝试从接口设计的角度,重新理解变化、边界与每一个工程师的责任。
接口隔离的是变化,而不仅仅只是入口
在日常讨论中,我们往往将接口等同于 HTTP 接口,将其理解为一次请求的入口。但实际上,这只是接口的一种表现形式,而不是其本质。
接口真正的意义,在于模块之间的协作边界。
它定义的不是从“哪里进入系统”,而是不同模块如何在不相互干扰的前提下协同工作。
可以将接口理解为两个人之间的协作契约:
一方的行为依赖于另一方的输出,但双方只需约定输出的形式与语义,而不关心对方的内部实现方式。只要契约稳定,内部如何演进,彼此都不应受到影响。
因此,良好的协作方式并不是多人共同开发同一个模块,而是通过清晰的模块边界实现隔离,每个模块都是一个完整的整体,只对外暴露必要的能力,对内则可以自然地演进。
就像画家不会在别人的作品上反复覆盖和修改,而是在自己的画布上完成创作。模块亦然,它应该被视为一件完整的作品,任何新增的功能都不应破坏其既有结构。
真正成熟的设计,并不是在已有结构上不断“修补”,而是在一开始就预留变化的空间。当变化可以在既定边界内被吸收,系统便能持续演进;而当变化必然破坏原有结构时,就应当被明确拒绝,或者通过新的模块、新的边界,重新构建更合适的设计。
接口的价值,正在于此。
隔离的不是访问入口,而是变化本身。
这是接口设计的抽象层理解,但它并不足以解释工程中的真实选择。
拉回现实
回到真实的工程环境,接口被破坏,很少时因为“不懂设计原则”。
更多的时候,都是现实的条件在不断挤压工程边界。
需求变更来的很急,
联调时间被压缩,
修改一个返回结构,似乎比重新设计一个模块要“更快”。
于是我们开始在以后接口上不断追加字段、塞特殊逻辑、绕过既有约束。
从局部来看,这是一次次“务实”的选择;
但从整体来看,整个系统的逻辑已然被篡改。
接口不再隔离变化,而是成为变化的集中入口。
模块不再是稳定的整体,而是变成了可以被随意侵入的公共区域。
这种失控并非一蹴而就,而是在一次”先这样把“”下次再改“的妥协中逐渐形成。
真正的问题不在于接口被修改,而在于修改是否仍然尊重模块边界。
作品意识
作品意识,是工程师在面对变化时,用来做取舍的内在约束。
所谓作品意识,并不是追求复杂设计,也不是拒绝变化。
我是否愿意为这个模块的整体性负责。
当你把一个模块视为“作品”,你会自然地产生几个判断:
- 新需求是否真的属于这个模块地职责范围
- 这次修改,是在扩展结构,还是在破坏结构
- 是否存在一种方式,可以在不侵入他人边界地前提下完整目标
正因为如此,具备作品意识地人,往往更愿意拒绝不合适地变化,或者选择重新划分边界,而不是在原有结构上不断修补。
这并不意味着效率更低。相反,它是在用更长时间的维度思考问题。
现实选择与长期结果
当这种取舍在系统中反复出现时,工程实践会逐渐分化出两种路径。
在工程实际中,确实存在着两种不同的选择路径:
一种选择是,把系统视为一组可以随时改动的功能集合。
在这种视角下,接口只是入口,模块只是文件夹,能跑起来就是成功。
另一种选择是,把系统视为由多个稳定作品组成的整体。
接口是边界,模块是承诺,修改意味着责任。
短期内,两者的交付速度可能没有明显差异;
但随着时间推移,系统的可理解性、可演进性和协作成本,会出现明显分化。
回到接口的意义
接口之所以重要,并不是因为它“限制了你能做什么”,
而是因为它保护了已经做对了的部分,不被随意破坏。
当接口能够隔离变化,
模块才能保持完整,
作品才能持续演进。
这也是为什么,接口设计最终反应的,并不是技术水平,而是工程师对自己作品的态度。
当一个系统允许随意修改他人模块时,它已经不再是协作,而是一种消耗。 接口存在的意义,是让变化有序发生,让作品得以保留。
