2026 2026年10月30日 28 min · 8.8k chars by yxc023

当代码可以随便生成,抽象还值不值钱?

AI 让写第二套实现的成本趋近于零,抽象曾经赖以成立的经济学动摇了。本文从真实接手经历出发,给出判断标准:会不会因同类理由变更、参数化污染信号、协议成本,并盘点 Sandi Metz、GitClear、arXiv 实证与 Fowler × Joshi 等业界讨论。

架构AI 工程软件设计设计模式抽象代码质量团队协作

一份写给工程师的判断指南:在 AI 大量生成代码的今天,我们该在哪些地方继续抽象,在哪些地方应该放心地重复。


引子:我接过的几段代码

回看这几年接手的项目,还有团队自己这几年写的代码,看到一个现象:当初那些”统一维护一份”的抽象,现在正在集体变沉。

先说清楚一件事:当时的决定并不算错。人工写代码时代,减少逻辑量、减少代码量、把一批相似功能统一维护起来以降低成本——这是标准的、也是正确的工程选择。今天回头看,变的不是当时的判断力,而是成本结构本身。

第一件:已经变沉的既有抽象。 接手时项目里已经有一些抽象,不算错,但比较重——一段面向多种应用的公共执行逻辑,抽出来的时候挺顺,代码也漂亮,但它面向的从来就不止一个场景。后来现实里冒出新挑战,数据维度要扩展,才发现这套抽象的功能在哪儿都得挂一个参数化开关:走 A 分支的时候要传这个,走 B 分支的时候要关那个。开关越加越多,抽象本身越来越沉。

而它真正让人难受的地方在于改动半径:每次要动这段流程,都得先想一遍”其他几个用它的应用会不会受影响”。改一个地方,要看五个地方。这不是技术问题——是抽象给自己加了一层耦合。当初省下的那点代码,现在要用”每次改动都要多看几个地方”来还。

第二件是存储:项目里把几个类型略有不同的相似实体,统一存在了一张表里。刚开始确实省事——一张表、一个模型、一套查询。但随着业务不断扩展,新的类型想要进来,就会发现它得往这个共用模型里适配:字段塞不进去就加一个含义模糊的列,枚举对不上就加一个特殊值。削足适履,越到后面越难受。后来改成各存各的模型,反而清爽了。

第三件是渲染:之前为了”只维护一份东西”,定了一套渲染协议——先约定每个字段该用什么组件(表格?标签?卡片?),再写一套统一的渲染逻辑去生成页面。协议本身是个不小的成本,而且它限制了表达力:内容本身有差异的时候,套在那套组件协议里,怎么调都不好看。后来干脆拆开,每个文件针对自己的数据模型,单独生成一套渲染页面代码,效果反而好得多。维护的代码看着变多了,但每一份都简单、都能看懂。

所以我现在的判断是这样的:

  • 抽象曾经很有价值,因为它能把复杂的逻辑想清楚,把一批类似的实体统一下来,用一套代码降低维护成本;
  • 但现在这个性价比反转了。类似但略有不同的业务规则,即使概念上可以泛化,完全可以写成完整两套,各用各自熟悉的词汇——代码重复就重复,反而更简单直接,更容易理解。存储也一样:与其共一张表互相适配,不如各存各的模型。

这不是说当时的抽象做错了,而是当时的约束条件已经不成立了。

2014 年 RailsConf 上 Sandi Metz 说了一句话,后来被写成博客,成了她最被引用的一段:

duplication is far cheaper than the wrong abstraction 重复远比错误的抽象便宜。

十年前这句话是一句少数派异议。2026 年 6 月,那篇 2016 年的旧文重新登上 Hacker News 榜首,400 多分、270 多条评论。评论区里出现最多的句子是:

在一个 AI 可以一次性替你生成五百行”看起来正确”的代码的时代,这条原则比任何时候都更需要被重新讨论。

这条原则不只是”过时”。它其实刚刚好对上了 AI 编程的真相。


一、一个正在发生的成本反转

抽象之所以在过去的五十年里显得如此正当,是因为写代码很贵。

一段重复的代码要写两遍,一个泛型基类要设计参数、要写文档、要在每次调用时考虑绑定值是否正确。当”写”是瓶颈时,抽象的经济学是压倒性的:省下的行数是实打实的成本节约。

但现在这个前提反过来了。

人工时代AI 时代
写第二套相似实现的成本高(人天)≈ 0(分钟级)
定一套协议 + 维护协议的成本高高(没变)
审查一段通用实现的难度中高(要同时持有通用语义 + 本次绑定)
表达力受限(被协议框住)的代价高高(没变)
等待”第三个实例出现”的成本高≈ 0
分叉(实现各走各的路)的成本高≈ 0

于是稀缺资源发生了转移:

优化目标从”代码量最小化”变成了”审查成本最小化”。

而抽象恰恰是提高审查成本的。一份通用实现 + 一个 type 参数,读者需要在脑子里同时维护两个模型;两份各写各的完整实现,每份只需要维护一个模型,而且每一份都直接读得懂业务规则。

而且抽象省下的从来只是”写”的成本,它自己还有一笔从未变便宜的成本:先定协议、把内容塞进协议、以及被协议框住的表达力。这三笔才是抽象真正在交易的东西。

这就是”重复就重复”这个直觉背后真正的道理:它不是懒,它是把成本从”写”挪到了”读”,而”读”现在恰好是我们更稀缺的那一侧。

所以回头看,当年的那些抽象不是”做错了”,而是它们在一个已经变了的世界里继续服役。接手时让人痛苦的,不是抽象本身,而是”抽象曾经的理由已经不成立了,但代码还在”。


二、把”抽象的收益”拆成四份,看 AI 到底打掉了哪一份

“抽象”其实是个打包概念,里面混着四种完全不同的收益。把它们拆开,才能看清哪些该扔、哪些该留。

收益 A:消除重复书写 ✅ 已被彻底打掉

省人力、省代码行。这部分收益在 AI 面前归零。你再也不会因为”写第二遍要花两小时”而被迫设计一个参数化的通用方案。

这是唯一被真正消灭的部分。

收益 B:强制不变量与一致性 ❌ 没被消灭,而且风险被放大

金额计算、权限判定、审计留痕、对外承诺口径——这些东西的正确性依赖”只有一份实现”。两个实现就意味着两个真相,漂移了就出事。

而且 AI 让这件事更危险,不是更安全:

  • 人工时代,复制粘贴第二套实现时,人会本能地觉得”不对劲”,多数人会回头抽公共基类;
  • AI 时代,生成第二套实现零摩擦,而且每份实现局部看起来都非常合理。

AI 让”分叉”变便宜,也让”分叉”变得更危险——因为分叉得太顺手,而且看起来都对。

收益 C:收敛概念与词汇 ❌ 与 AI 完全无关

把纷杂的自然语言现实梳理成有限、标准的数据模型和行为——这件事的价值来自”业务本身有客观结构”,不是来自”代码要省行数”。

如果今天允许每一份实现各用一套字段名、各用一套状态定义,那么三个月后没有人能确定”这两个东西的待审核是不是一回事”。概念分裂的代价与 AI 无关,而且通常远大于代码重复。

放到我这两年接过的代码上:那些”为了抽象而抽象”的重,最终累赘的地方往往不是逻辑复杂,而是同一个东西在不同地方被叫成不同的名字、赋予了不同的含义。这种分裂不会报错,只会在需求变化时让人花半天确认”这两个到底是不是一回事”。

收益 D:降低读者认知负担 ⚠️ 方向反转

历史上有句谚语:“代码行数 ≈ 人的心智负担”。这其实从来不完全对——真正的负担不是行数,而是要同时在脑子里维护多少个心智模型。

  • 通用实现 + 参数绑定:负担 = 通用语义 + 绑定值,两层;
  • 两份具体实现:负担 = 每份各自一层。

现在稀缺的是审查时间,抽象增加审查负担。所以这一项今天的结论是反的。

小结

抽象的价值来源,从”消除重复书写”迁移到了”消除概念分歧”和”保证不变量”。 代码层面的统一程度可以下降;领域模型层与词汇层的统一不能省。


三、核心判据:它们会因同类的理由而变更吗?

这是整篇文章最实用的一条。判断”要不要统一”,不要问”像不像”,要问”会不会一起改”。

未来某一次业务变更,会不会同时改到 A 和 B?

会一起改不会一起改
判定同一概念的两种表现两个恰好相似的概念
模型层共享实体、字段、状态机、词汇完全独立建模
代码层各写各的(各用各自熟悉的业务词汇)各写各的(本来也没得统一)

例 1:同一概念 —— 一段面向多种应用的公共流程

一段逻辑同时服务多种应用,抽象出来的时候确实”消除了一堆重复”。但如果这些应用的变化节奏不一样——比如一类要支持数据维度扩展,另一类两年不动——那把它们焊在一起,改动成本就从”改一处”变成”改一处 + 想清楚会不会影响另外几处”。

这时候正确的做法是:共享模型与词汇(这些应用到底是什么、字段怎么定义、状态怎么流转),但执行流程各写各的。每份实现只服务自己那个场景,改动半径为零。

例 2:两个概念 —— 渲染逻辑

之前为了”只维护一份东西”,我们定了一套渲染协议——先约定每个字段用什么组件,再写一套统一的渲染逻辑去生成页面。协议限制了表达力:内容本身有差异的时候,套在那套组件协议里,怎么调都不好看。后来拆开,每个文件针对自己的数据模型单独生成一套渲染代码和页面,效果反而好得多。

这不是”抽象没做好”,这是两个概念恰好长得像。它们的差异不在数据,在最终呈现的效果。共用一套渲染逻辑,等于强行让两个不同的东西用同一种表达方式——省下的那点维护时间,全赔在效果上了。

例 3:两个概念 —— 共用一张表存相似实体

几个类型略有不同的相似实体,统一存在一张表里。短期省事,长期被业务扩展逼着做适配:新类型进来,字段塞不进去就加一个含义模糊的列,枚举对不上就加一个特殊值。这是典型的削足适履——共用模型反过来绑架了本来不同的业务。

代价还不止于字段:查询会越来越绕(每多一个类型就多一个 where 分支),约束会互相干扰(一个类型的必填规则卡住另一个类型),数据模型与业务的概念开始漂移。

处理方式就是本文的主张:各存各的模型。数据库层面多几张表、几份 DTO,换来的是每个业务都能用自己的字段、自己的约束、自己的语言。

例 4:两个概念 —— 被参数化开关撑起来的抽象

功能本身不复杂,却被一堆参数化开关撑起来,走哪条分支都要先读一遍参数怎么传。这通常说明当初被统一的那几个场景,根本不是同一个东西,只是写代码的时候看起来像。

这跟第一章说的”参数化污染”是同一个信号的两面:开关是抽象开始腐化的最早可见的痕迹。

这条判据在业界有出处

2026 年 6 月 HN 那场讨论里,被反复引用的核心问题几乎一字不差:

文章讨论的正是”你还不知道真相来源有几个”的情况。这两个位置用的是同一套算法,还是略有不同的版本?更重要的是,它们会因同类的理由而变更吗?——jonahx

同一位评论者还有一句更锋利的:

最关键的是,错误的抽象破坏了局部性——而那其实是你修改代码时唯一真正在乎的属性。我只想做这一个改动,不用担心对系统不相关部分的副作用。

“局部性”是比”复用”更重要的目标。 在 AI 时代尤其如此:你要改的是一段局部代码,而不是一个被 5 个调用者共享的参数化引擎。


四、参数化污染:识别”假相似”的现场信号

上一条判据在实践中需要一些抓手。有一个非常可靠的现场信号:

为了把 A 和 B 塞进同一份实现,你必须给它加 if / flag / 参数维度。

// 统一审核流程
applyRule(order, type)
  if (type == STANDARD) { ... }
  if (type == VIRTUAL)   { ... }
  if (type == COOPERATION) { ... }   // ← 第三个类型冒出来了

参数一多,状态空间成倍膨胀。每个调用者都要理解”通用语义 + 本次绑定”两层。通用实现开始长出第三个布尔或枚举参数时——这就是拆分信号。

这条机制在业界被描述得更加具体。Dejan Menges(Vinted Staff Engineer)写到:

AI agent 会写出能跑但架构上错的改动:实现了一个已经存在的东西、为已解决的问题引入第二套抽象、把新行为放在没人会想到去找的地方。改动能跑,PR 是绿的,任务完成了。直到下一次改动——这时另一个开发者或 agent 必须判断:两个实现里哪一个才是真的?

而 Reveneau 说得更准:

让模型处理三个相似案例,它通常会产出一个恰好能处理这三个的巧妙东西。这不是模型的 bug——它读过大量”合并相似案例是对的”的代码,它只是缺了路线图:它不知道第二个案例下周就要换方向。

所以参数化污染的那一刻,就是抽象出错的那一刻。


五、抽象的隐藏成本:先定协议,才能写代码

前面说的都是抽象”跑起来之后”的成本。还有一笔成本发生在动手之前:任何像样的抽象,都要求你先定下一套协议。

渲染是最清楚的例子:

抽象方案(我们走过的路)                    直接方案(现在能走的路)
─────────────────────────────              ─────────────────────────────
① 定一套渲染协议:                          针对每个数据模型,
   字段类型 → 组件的映射规则                 单独生成一套页面代码
② 写一套通用渲染逻辑
③ 每份内容都往协议里塞                       表达力不受协议限制
④ 内容有差异时:效果不好                     想要什么效果就写什么

第 ① 步和第 ② 步是实实在在的维护成本,而且会一直付下去:协议本身要演进,映射规则要覆盖越来越多的字段类型,而协议一旦定下,所有业务都被框在它能表达的范围里。

而这套流程存在的唯一理由是”要维护一份”。在代码可以随便生成的今天,这个理由不成立了——针对一个数据模型,单独生成一套精美的渲染页面代码,完全可行。生成出来的效果不好吗?比通用模板套出来的更好看,因为它本来就是照着这个模型写的。

所以抽象的完整账单是这样的:

抽象的代价项过去现在
写第二套实现的成本高≈ 0
定协议 + 维护协议的成本高高(没变)
通用实现的审查成本中高
表达力受限的代价高不变(现在甚至可以做得更好)

中间两行没有因为 AI 而变便宜,第一行变便宜了,第三、四行变贵了。这就是性价比反转的全部机制。

这也解释了为什么”直接生成一套专属的渲染代码”不是偷懒,而是正确:它省掉的是协议成本,避开的是表达力限制,代价只是多了一份代码——而这份代码现在几乎不要钱。

回头看引子里那三件事,会发现它们其实是同一件事的三个切面:

接手时看到的它其实是哪种成本
公共流程越改越要看多个调用方耦合成本(抽象给自己加的)
参数化开关越挂越多协议成本(抽象要维护的那套约定)
共用一张表、类型来了要适配表达力成本(被共用模型框住)

三笔都是抽象的固有成本,而且没有一笔因为 AI 而变便宜。真正变便宜的只有”写第二份实现”这一项——而那恰恰是抽象本来要解决的主要痛点。当唯一的优势消失,抽象的性价比就反转了。


六、重复不是免费的:它的账单要单独记

“代码重复就重复”是对的,但重复有它自己的成本结构,而且这份账单不随 AI 下降。

重复的隐藏成本具体内容对策
漂移检测负担N 份实现要定期确认”这 N 套规则现在还一致吗”一致性测试 / 共享测试数据 / 单一规则源
词汇漂移两套实现各自演化术语,最后没人知道两边的”待审核”是不是一件事术语映射表(glossary)
导航成本想知道”这条规则到底在哪”要看 N 处索引/目录标注
承诺不一致对内系统和对客系统给出不同答案⚠️ 跨边界口径必须单一真源

反过来,抽象也有隐藏成本:leaky generality(通用实现被特例撑破)、参数维度膨胀、审查负担。

所以正确的做法不是在”抽象 vs 重复”里二选一,而是逐项比账。 最优解通常长这样:

┌──────────────────────────────────────────────────┐
│  领域模型层(共享)                                │  ← 统一实体 / 状态机 / 词汇
│  概念、字段、不变量                                │     这层必须统一
└──────────────────────────────────────────────────┘
                    ▲
┌──────────────────────────────────────────────────┐
│  规则 / 规格源(单一真源,可读可测)                │  ← 抽象的真正落点
│  决策表 / DSL / spec 文档 + 示例                  │
└──────────────────────────────────────────────────┘
        ▲                ▲                ▲
  ┌───────────┐    ┌───────────┐    ┌───────────┐
  │ 实现 A     │    │ 实现 B     │    │ 实现 C     │  ← 各用各自词汇
  │ 完整、独立 │    │ 完整、独立 │    │ 完整、独立 │     从同一规格生成
  └───────────┘    └───────────┘    └───────────┘
        ▲
  ┌──────────────────────────────────────────────────┐
  │  安全带:一致性测试 + 术语映射表                  │
  └──────────────────────────────────────────────────┘

要点:

  1. 规则写一次,实现写多次——业务真相单点可查、可测、可直接贴给 AI 当上下文;
  2. 一致性测试作为守门人——同一组输入喂给多套实现,断言输出一致(或断言差异符合预期)。这是”允许重复”的安全带;
  3. 模型层是共享词汇层——它保证两边说的是同一件事,但不强求两边用同一套代码。

这正是”抽象上移”:抽象没有消失,它从代码搬到了规格和词汇。


七、什么必须保留单一真源(不可重复的清单)

有些地方,“两份实现”不是省钱,是制造风险:

  • 金额 / 账务 / 费率计算(精度、单位、四舍五入)
  • 权限鉴权判定(两份授权逻辑 = 一个漏洞)
  • 审计留痕 / 操作日志
  • 对外承诺口径(合同、SLA、对客规则)
  • 数据模型与存储约束(表结构、唯一键、外键——数据库层面本来就在统一)
  • 核心状态机的合法迁移集合

判断口诀:

错误代价高 + 必须处处一致 → 单一真源 错误代价低 + 各场景独立演进 → 允许重复


八、业界说了什么:证据盘点

这个话题在 2025–2026 年已经从”少数派口味”变成了”有实证支撑的争论”。下面按证据强度分组。

8.1 强支持

Sandi Metz《The Wrong Abstraction》(2016) — “duplication is far cheaper than the wrong abstraction”。她给出了错误抽象的 8 步退化路径:

程序员 A 发现重复 → 抽出公共方法并命名 → 代码完美,A 满意离开 → 时间过去 → 新需求来了,现有抽象”几乎”够用 → 程序员 B 出于对既有代码的尊重,加一个参数、加一个分支 → 第三个需求、第四个参数、第五个 if → 到第八步时,你出现了,对着一堆纠缠的条件逻辑,试图理解哪些分支属于哪个调用者。

解法同样简洁:把抽象内联回去(“the fastest way forward is back”)——让每个调用者只保留自己真正需要的代码,再从头观察哪些相似性是真实的。

2026 年 6 月,这篇 2016 年的旧文重登 HN 榜首(400+ 分 / 270+ 评论)。

Justin Holt《The Case Against DRY in the Agentic Age》 — 提出 RYAN(Repeat Yourself As Needed):

重复是一种工具,不是罪过。抽象要挣得自己的位置,而不是因为”两件事恰好在某个星期二看起来像”。

  • 放心重复代码。两个渲染相似 markup 的模板,可以就是两个模板。
  • 不要重复知识。业务规则、税额计算、权限检查,应该活在一处。

这两句话几乎就是我全文的结论:知识/模型单点,代码可重复。

arXiv 2603.27130《真实仓库 AI 代码大规模实证研究》 — AI 生成代码 content ratio 更高、lexical density 更低,作者总结为 “Explicitness over Compactness”:

AI 生成的代码倾向于用重复的、显式的构造来表达逻辑,而不是紧凑的抽象。

这是最直接的实证背书:AI 自己就在往”显式、展开、好读”的方向产出代码。

arXiv 2610.24093《Does AI-Assisted Development Homogenize Software?》 — 50 个长期存活的 Java/Python 项目、三个时代(pre-LLM / LLM-assisted / agentic)对比:语义与语法相似度没有上升(Java 甚至显著下降),Python 无显著差异;质量指标基本稳定,agentic 时代的 code smell 与 SQALE 密度反而更低。

这反驳了”AI 必然把代码库搞成一片重复”的悲观论。

arXiv 2607.13077《The Hitchhiker’s Guide to Monoculture》 — Kaggle 2019→2026 提交物研究:AI 让语法趋同(连 seed = 42 都收敛),但 “approach / intent” 没有证据表明同质化。

推论很关键:“写法统一、思路保持多样”是可行的——这正好对应”各写各的但遵守统一约定”这种团队形态。

grapeot《超越DRY:AI原生软件工程的思考》 — 一年高强度 AI 开发后的第一手实践:

我并没有有意识地避免重复工作,甚至有意违背了软件工程最核心的原则——DRY。每次我想画流程图、做简单的可视化,就直接让 AI 帮我写,而没有把它们抽象成一个可复用的库。可是奇怪的是,我的开发效率并没有降低。

他进一步提出 UGS(User Generated Software)与 Generative Kernel 交付观:AI 原生设计应该是”激进透明”——暴露细粒度控制、提供原始错误信息、交付给 AI 看的知识。结论:

我们依然要不遗余力地避免在核心能力上重复自己,但我们允许、甚至鼓励 AI 在生成最终应用时,为满足个性化需求而进行有意义的重复。

8.2 保留意见

GitClear 2025(2.11 亿行改动数据):2024 年”≥5 行的重复代码块”出现频率同比 8 倍;copy/paste 首次超过 moved。

GitClear《The Maintainability Gap》(2026-06):2023–2026 共 6.23 亿次改动——refactoring 下降 70%、legacy 维护下降 74%、代码块重复上升 81%、error-masking 上升 47%。

这两组数据揭示了”允许重复”的真实代价,而且这个代价不在”重复”本身,在没有人再回头合并。

Dejan Menges《When code gets cheaper, architecture gets more expensive》(2026-10-11):

AI agent 能产出正确的改动,却不理解它属于哪里。保持系统内聚,正在变得更重要,而不是更不重要。

Martin Fowler × Unmesh Joshi《Conversation: LLMs and Building Abstractions》(2025-08-26) — 这条不是反对,而是给”抽象该放哪”定位。他们借 Brooks《No Silver Bullet》区分:

本质复杂度:软件实体本质的困难——数据集、关系、算法、函数调用。偶然复杂度:今天伴随生产而来的、并非本质的困难。

LLM 擅长削减偶然复杂度(语法、框架集成、样板代码)。但”写软件”本身是:切分问题、把相关数据与行为绑定、选择暴露意图的名字——

编程有两个深度交织的活动:发现并稳定抽象(创造性工作,人主导),和应用稳定抽象(有了稳定的词汇,LLM 就能机械执行)。

于是抽象的落点被重新定位了:从”代码复用”移到”领域词汇与稳定命名”——正好落在你我共识的那一层。

他们还提到 USI(Upfront Specification Impossibility):第一版规格最多是一个假设。这提醒我们:规格源本身也需要迭代,不能一次写死。

Grady Booch(UML 之父):AI 是新的一层抽象,软件工程的本质难题从未消失。

彭鑫(复旦)《智能化时代的软件工程:拥抱大模型的正确姿势》:瓶颈不在”AI 能否写好代码”(执行复杂度),而在”人如何准确高效地传达复杂任务目标”(目标传达复杂度);专家知识需要体系化、结构化沉淀。

大淘宝技术《AI Coding 思考》:企业级场景真正的瓶颈是专家知识未体系化、信息熵过高、上下文工程靠”人肉手艺”、知识重复建设。

这两条与”共享的是知识与词汇,而不是代码行数”完全同向。

8.3 业界共识

几乎没有人主张”抽象不重要”。真正的共识是三条:

  1. 错误抽象的代价在 AI 时代上升了——AI 的错抽象看起来更专业、更光滑,审查者更容易放行;
  2. 写第二套的代价下降得更多——所以”再等等看会不会出现第三个实例”的等待成本大幅下降;
  3. 因此抽象的门槛应该抬高、落点应该上移——从代码复用,移到领域词汇、领域模型、不变量与规格。

九、一个副产品:Convention over Abstraction 真的成立了

Ward Cunningham 当年说 “Convention over Configuration”,本意是”约定优于配置”。

今天更贴切的说法是:约定优于抽象(Convention over Abstraction)。

理由很实在:AI 生成与修改代码,靠的是模式匹配与结构可预测性。一份”整齐划一、意图直白、允许重复”的代码库,对 AI 的读写可靠性,远高于一个”精巧的通用引擎 + 一堆配置”。

通用引擎的分支组合空间,正是 AI 最容易出错的区域——生成的代码”看起来对”,实际漏了某个参数组合。反过来,两份各写各的完整实现,每份都是自洽的直白逻辑,AI 改动的爆炸半径也小得多。

所以在 AI 时代,代码库形态的最优解正在从复用最大化转向结构可预测性最大化:

  • 命名统一、目录形态统一;
  • 每份实现自洽、术语用业务语言;
  • 通用机制用配置表达,而不是用隐式分支表达。

十、什么时候”重复”会翻车

原观点有明确的边界。以下情形需要收回:

  1. 跨团队 / 多实例:5 个以上团队各写一套”类似”规则,口径必然分裂;
  2. 规则被外部承诺:对客或对监管承诺过的口径,不允许两份实现;
  3. 强演进的领域:某天需要把 A、B 一起重构,重复版本会让改动成本翻倍;
  4. 错误代价不对称且不易发现:静默的算错、漏掉的分支,测试覆盖不到就永远潜伏;
  5. AI 加剧重复:模型每次生成都可能”再发明一遍”相似逻辑,两份实现会像”不同作者写的”——风格、命名、边界处理都不同,持续制造阅读噪声。

判断重复是否翻车,看一件事:这两份实现分歧了,谁会发现、多快会发现、后果多严重。 没人发现 = 灾难;测试一跑就炸 = 自由。


结语:稀缺的不再是”怎么抽象”,而是”何时抽象”

在一个 AI 可以替你写出合规代码的时代,真正的稀缺能力不再是”怎样抽象”,而是”何时抽象”。

后者需要的不是技巧,是耐心——是对业务领域持续观察后形成的判断,以及在沉没成本面前敢于把抽象拆回去的冷静。

在代码可以被无限生成的时代,最快的路有时候不是抽出来,而是——就让它重复。

评论