软件工程的惯性
软件工程有很强的惯性。
很多今天被当成常识的工程实践,并不是永恒正确的真理,而是在某个成本结构下形成的优化。过去写程序很贵,培养程序员很贵,理解需求很贵,验证实现也很贵。所以软件工程自然围绕一个目标展开:尽量少写重复代码,尽量复用已有实现,尽量把共同逻辑沉淀成库、框架、平台。
这在过去是合理的。
但 Agent 改变了其中一个关键变量:写程序的边际成本正在快速下降。一段局部业务代码,一个页面组件,一个数据转换逻辑,一个一次性的自动化脚本,过去可能需要工程师花半天到几天,现在可以由 Agent 在很短时间内生成、修改、重写。
这不意味着软件工程不重要了。恰恰相反,软件工程会变得更重要。只是它要解决的问题变了。
当写代码变便宜之后,真正昂贵的东西不再是代码本身,而是理解、协调、验证和演进。软件工程的组织方式也应该围绕这些新瓶颈重新设计。
第一个需要重新审视的,就是代码复用。
代码复用的旧前提
传统软件工程里,代码复用几乎是一种默认美德。
不要重复自己。抽象公共逻辑。把相似的实现提取出来。做共享库。做平台能力。让所有团队使用同一套基础组件。
这些实践背后的前提是:代码很贵,所以应该减少重复。多写一份代码意味着多一份实现成本,多一份测试成本,多一份维护成本。只要两段代码看起来足够相似,把它们合并成一个公共实现,通常就被认为是工程质量更高的选择。
但这里有一个容易被忽略的问题:复用从来不是免费的。
复用节省的是复制成本,增加的是耦合成本。
过去复制成本足够高,所以我们愿意承受更多耦合成本。现在 Agent 降低了复制成本,耦合成本就应该被重新计价。
复用的代价是兼容性债务
代码复用带来的最大问题,不只是抽象可能不够优雅,而是它会把新增代码变成一次兼容性工程。
一段新代码本来只需要解决当前问题。但一旦它进入复用体系,就必须同时承担过去、现在和未来的约束。
它要理解已有抽象为什么长成这样。它要服从已有接口、数据结构和调用方式。它要避免破坏已有调用方。它还要为未来可能出现的场景预留扩展空间。
于是新增功能不再是线性地增加代码,而是在已有兼容性网络里寻找一个不会引发连锁反应的位置。
这就是复用的真实成本。
共享代码一旦被更多地方依赖,就会逐渐失去演进自由。一个接口不能随便改,一个参数不能随便删,一个默认行为不能轻易改变。即使当前需求很简单,也要考虑已有调用方会不会受影响,未来调用方会不会被限制。
重复代码的维护成本通常是局部的。某个业务场景变了,改那一处就好。
复用代码的维护成本往往是全局的。一个公共模块发生变化,影响的是所有依赖它的地方。
所以在 Agent 时代,一个重要判断是:
代码复用节省的是复制成本,增加的是兼容成本。当复制成本被 Agent 大幅降低后,兼容成本就成为更值得警惕的部分。
不是取消复用,而是提高复用门槛
这并不是说软件工程不再需要代码复用。
更准确的说法是:代码可以不复用的范围变大了。
过去因为写代码贵,我们倾向于尽早识别重复、抽象公共逻辑、推动复用。但当 Agent 降低了生成和修改局部代码的成本之后,很多过去值得复用的代码,现在未必值得复用。
复用仍然有价值,但它不应该再是默认选择。它应该变成一个需要证明收益的选择。
很多一次性的、业务强相关的、变化频繁的代码,与其抽成公共模块,不如保留在局部上下文中。这不是放任混乱,而是承认一个事实:局部重复有时候比全局耦合更便宜。
在 Agent 时代,重复代码不一定是坏味道。错误的共享抽象才是昂贵的坏味道。
真正仍然值得复用的,应该是那些稳定、低变化、边界清晰、语义强一致的部分。比如协议、认证授权、加密、安全边界、数据库驱动、成熟算法、核心基础设施。
这些部分的价值不在于少写几行代码,而在于它们已经被长期验证。重写它们不会带来多少收益,反而会引入新的风险。
需求越快,复用越应该谨慎
这个变化在需求快速变化的领域尤其明显。
复用隐含着一个判断:这些场景足够相似,并且未来会继续相似。
但在需求快速变化的领域,这个判断经常不成立。产品早期、增长实验、AI 应用、运营后台、内部工具、业务流程系统,很多需求本质上都还在探索。今天看起来相似的两个流程,明天可能因为用户分层、商业策略、合规要求、数据口径不同而走向完全不同的方向。
这时候如果过早复用,就不是在降低成本,而是在提前固化一个还没有被验证的业务理解。
一个常见的问题是:抽象不是因为领域稳定而产生的,而是因为代码相似而产生的。
但代码相似不等于业务相同。
两个页面都要展示列表,不代表它们应该共用同一个列表组件。两个流程都有审批,不代表它们应该共用同一套流程引擎。两个接口都在做字段转换,不代表它们应该进入同一个 mapper。
在变化快的领域,局部重复反而保留了演进自由。每个场景可以按自己的业务方向独立变化,不需要为了一个共享抽象互相迁就。
所以,需求越不稳定,复用越应该谨慎。先让代码跟着业务自然分化,等模式真正稳定之后,再考虑把稳定部分沉淀出来,可能比一开始就追求复用更合理。
在快速变化的领域,重复代码保留选择权,过早复用消耗选择权。
复用知识,而不是默认复用代码
Agent 时代更应该复用知识,而不是默认复用代码。
代码只是知识在某个时间点、某个技术栈、某个业务场景下的表达。真正昂贵的不是这份表达,而是产生这份表达的知识。
这些知识包括领域概念、业务规则、接口契约、数据模型、测试用例、设计决策、边界条件、错误案例、性能约束、安全要求。
过去因为代码生成成本高,所以我们倾向于复用代码本身。但现在,如果 Agent 可以基于清晰的知识重新生成局部实现,那么很多场景下,我们不必强行共享同一份代码。
更合理的组织方式是:共享知识、契约和验证体系,让具体代码保持局部性。
也就是说,不一定要求所有相似场景都调用同一个模块,但它们应该遵守同一套业务规则、同一组接口契约、同一批测试用例。具体实现可以由 Agent 根据当前上下文生成、修改或重写。
这样既能避免知识分裂,又能减少代码层面的耦合。
完备的部分不要重写
当然,复用知识不等于重新发明一切。
对于已经完备、稳定、边界清晰、长期验证过的部分,继续复用代码是合理的。甚至应该避免重写。
数据库驱动不需要重写。认证授权不应该随便重写。加密、安全边界、基础协议、成熟算法、核心基础设施,这些地方的主要价值不是实现速度,而是可靠性和验证历史。
Agent 降低的是代码生成成本,不是验证成本。越是底层、越是安全敏感、越是被广泛依赖的代码,验证成本越高,重写风险越大。
所以这里的判断不是简单的反复用,而是区分不同层次:
不稳定的业务部分,优先复用知识,谨慎复用代码。
稳定且完备的基础部分,继续复用代码,不做无意义重写。
软件工程应该重新计价
软件工程的很多惯性来自代码昂贵的时代。
在那个时代,少写代码就是收益,复用代码就是优化,抽象公共逻辑就是工程成熟。但 Agent 让这个成本结构开始变化。写代码变便宜之后,我们应该更认真地审视那些因为少写代码而引入的复杂性。
未来的软件工程不应该继续以减少代码行为中心,而应该以控制耦合、保留演进自由、沉淀知识和提高验证效率为中心。
代码复用不会消失,但它的地位会变化。
它应该从默认选择,变成需要证明收益的选择。
而在需求快速变化的领域,软件工程更应该追求的不是写出最通用的代码,而是沉淀最清晰的知识,让局部实现可以低成本地生成、替换和演进。
Agent 降低的是代码生成成本,不是知识形成成本。
这才是软件工程需要重新组织的地方。
DISCUSSIONS
评论
使用 GitHub 账号参与讨论,评论将同步到 GitHub Discussions。