开发者生态
morning
停止编码的那天,就是失去架构判断力的开始:一位 30 年架构师的 AI 生存指南
2026-05-09
1 阅读
傅宇琪,Tina
在AI Coding飞速发展的当下,工程师的价值正从“如何实现”转向“解决什么问题”,那么,手敲代码还有意义吗?作为一名坚持编码近 30 年的架构师,微软最有价值专家 (MVP)、开源项目创作者、现任 Aviva Solutions 的代码架构师Dennis Doomen的观点直截了当:如果你不深入代码,就无法做出优秀的架构决策。 最近,Dennis在播客节目中,与主持人 Patrick Akil 对话,他以大量一线经验为基础,探讨了一个更现实的问题:在 AI 可以生成代码的时代,我们究竟该如何保持对代码质量的掌控?基于该播客视频,InfoQ 对内容进行了整理与部分删改。 核心观点如下: 作为架构负责人,同时仍保持动手实践,这是团队中唯一有效的软件开发方式。软件工程的核心,无论过去还是未来,都是在已有系统与不断增长的复杂性之间维持平衡。如果对过去的决策缺乏理解,却仍机械遵循,就会不断累积复杂性,而时间会放大这一问题,甚至决定系统成败。即便未来我们可能不再需要编写代码,现阶段仍然需要对 AI 生成的结果进行接管和维护。无论是提交记录还是代码评审说明,都应尽量记录决策意图,而不仅是技术细节。 成为高效软件架构师的唯一方式 Patrick:你曾说自己不愿意全职做会议演讲,因为你太热爱现在的工作了。 Dennis:我也不认为有必要全职从事演讲,我仍然希望亲自参与实践。我更愿意称自己为“动手型架构师”或“编码型架构师”,几乎所有分享内容都源于我的一线经验。如果停止编写代码,不再亲自构建并上线生产系统,就会逐渐失去这些经验。 我现在 52 岁,从事这一领域已近 30 年,几乎无法想象自己停止编码。幸运的是,我的工作通常兼具架构设计与团队协作,我既是架构师,也是团队成员,会与开发者一起编写生产代码,从中能够获得大量实践经验。同时,我也能向开发者展示:只要稍微调整方法,代码的可维护性就能显著提升,这一点非常有价值。此外,在实践中还会不断遇到框架限制,学习新技术、新范式,这些都极具价值。因此,我通常只分享自身经验,而不是单纯介绍新技术,因为后者已有很多人可以胜任。我更愿意讲述日常工作中的真实经历,包括遇到的困难与取得的成功。 Patrick:作为架构负责人,同时仍保持动手实践,这是否是团队中最有效的软件开发方式? Dennis:我认为这是唯一有效的方式。我接触过许多企业架构师,他们通常关注高层设计,例如策略或信息架构,但往往缺乏一线经验,难以判断某种方案是否可行,或某种技术路径对长期可维护性与可持续性的影响。对我来说,软件架构师若想真正发挥作用,必须清楚自己在做什么,并通过实践不断验证设想,需要亲自观察方案在实际中的表现。即使只是修复现有代码库中的缺陷,也极具价值,因为可以从中学到大量经验。我曾多次以顾问身份加入团队,发现他们在维护代码时面临困难,例如高耦合、结构混乱等问题。 当从更高视角审视时,往往会发现其架构本质上类似某种成熟模式。但问题在于,当前团队已经完全失去了对原始架构理念的理解,甚至不知道其底层设计思想。他们只是机械地复制项目结构与文件夹,而不理解其背后的原因,这种教条化做法反而削弱了优化和简化代码的能力。如果不深入代码库,很难发现这些问题。 在从零开始设计系统时,架构师通常会基于功能与非功能需求做出合理假设,但将这些设计真正落地,并非仅靠文档即可完成,开发团队仍会在实现过程中犯错。架构本身也包含假设,例如是否需要某种抽象,或是否采用特定模式,最终可能发现方案过于复杂或性能不足,需要调整。有时团队经验不足,也难以判断某种模式是否适用。因此,这一过程本质上是持续迭代的:设计、实现、反思、再调整,这与敏捷开发非常相似,也是工作的重要组成部分。 Patrick:我认为软件工程的核心,无论过去还是未来,都是在已有系统与不断增长的复杂性之间维持平衡。如果对过去的决策缺乏理解,却仍机械遵循,就会不断累积复杂性,而时间会放大这一问题,甚至决定系统成败。 Dennis:如果你意识到系统中存在不必要的复杂性,就需要持续投入精力去消除它。但实践中常会面临权衡,例如某个模块过于复杂,却遵循统一模式,是否应打破模式以简化该模块。如果这样做,系统的一致性会受到影响,部分开发者更倾向于保持一致性,即使代价是更高复杂度。我的观点是,应将模块视为边界,在该边界内保持一致性即可,而优先简化模块本身,因为这将显著提升可维护性。许多开发者在抽象、单元测试范围等问题上感到困惑,本质上也是复杂性带来的问题。 关于避免重复(DRY)原则,我持相对务实的态度:在某些情况下,我会有意识地复制代码,以降低耦合,但这必须是经过权衡的决策,而非盲目复制或完全避免复制。我观察到,许多有 10 至 15 年经验的开发者,在掌握设计模式后,往往会过度依赖这些模式。当你提出当前并不需要某种抽象时,他们常常会引用开闭原则或单一职责原则进行辩护,但这些抽象往往只是为未来的可能性做准备,而非现实需求。例如,有人会为了未来可能支持多种数据库而设计复杂抽象,即使当前并无此需求。但不同数据库在语义上的差异,使这种抽象往往难以真正成立。 Patrick:如果存在一套固定规则,严格遵循是否会更简单? Dennis:理论上可以想象这样的情况,例如一种完全统一的标准,但现实并非如此。 Patrick:我更感兴趣的是“规范与务实”的平衡,以及当下与未来的取舍。随着 AI 辅助开发不断加速,我们或许会逐渐不再关注实现方式本身,只要系统最终是可维护的即可。 Dennis:我认为在未来的某个阶段,人们可能真的不再关心代码本身,就像科幻作品中那样,只需表达需求,系统便能自动完成。去年,我开发了一个 .NET 的开源 HTTP Mock 库,起因是现有工具无法满足需求,于是我开始自行构建,并整理需求与 API 设计。 出于好奇,我将 GitHub issue 分配给 Copilot。令人惊讶的是,它生成了一个高质量的开源项目,基本实现了所有需求,并遵循了我的编码规范。随后我通过评论不断补充需求,例如增加断言方法、支持不同版本等,它也能够很好地完成这些任务,甚至可以自动拆分项目、生成文档示例。在此基础上,我继续手动优化,并将其视为自己的代码进行迭代。现在,我采用人机协作的方式开发:部分功能由 AI 生成,部分由我完成。目前代码中存在一些不完全符合我标准的部分,例如方法较长,但我选择接受这一现实,并在后续逐步重构。 Patrick:只要功能正确、测试通过,就可以接受,而不必立即优化。 Dennis:确实如此。代码本身并不差,也遵循一定规范。我仍在不断尝试新的工具与方法,同时会重点审查测试,确保其能够准确反映预期行为。测试不仅用于验证功能,也帮助我理解系统行为与 API 设计。在实践中持续迭代,而对于重复性任务,我通常会优先交由 AI 处理,以提高效率。 即使是在日常项目中,我也会让 AI 生成额外的测试用例,以确保覆盖率足够全面。但随后我一定会逐一审查这些测试,确认它们确实达到了预期目的,同时也符合我偏好的编码模式。在此基础上,我会要求 AI 进行调整,并同步更新指令文件,使其在下一次生成时更贴近我的规范。虽然这并不能完全保证结果,但这已经成为当前较为有效的工作流程。 测试在 AI 时代成