先设计再写代码,还是先实现再重构?AI 编程让这种选择变的简单
在传统手工编程时代,经常会有争论:先把各种细节设计清楚再动手写代码?还是先实现,实现后再回过头来确定设计重构代码。

我在大学学软件工程的时候,书上说要先做概要设计再做详细设计,详细设计要详细到类和方法。概要设计就是现在说的 System Design,是系统层面的设计,也是现在复杂软件系统在开发之前必做的事情,面试高级的开发岗位也少不了要面试系统设计。
但是对于详细设计,我早期一直不得要领,从来没办法去做详细的设计,一方面是因为水平不够,一方面实际软件开发充满了不确定性,需求不确定,技术方案不确定,写着写着需求就变了,或者发现技术方案不太可行,需要改,所以常常是边写边想,等到功能实现完才能想清楚设计,后面再尝试去重构。

当然也有人说,高水平的架构师可以让架构足够灵活,能降低适应变更的代价,但实际上,这样灵活的架构或者框架通常就是代价本身,看似灵活,但是实际上极大的增加了维护成本,有时候得不偿失。
后来我才明白,早期软件工程强调详细设计,是因为早期软件工程很多地方是借鉴自建筑工程,建筑工程会有概要设计和详细设计,但建筑工程相对确定性比较高,不像软件工程中充满了不确定性。
回过头来说 AI 编程
当我们使用 AI 编程时,有一点很大的变化就是极大的缩短了从设计到编码的成本和时间,也就是哪怕你的详细设计还不是很清晰,也可以实现一个版本出来,基于实现出来的版本,能帮助你梳理清楚需求上的不确定和技术实现上的不确定,等到梳理清楚了,再去调整设计和重新实现就相对简单多了。
所以配合 AI 编程,让先详细设计再实现变成了可能,或者说本质上是两者的融合:先设计 -> 写代码 -> 改进设计 -> 写代码。只是在实践上,变成了:
先设计,把设计结果写成简单的AI看得懂的提示词
用提示词生成代码
验证生成的结果
根据验证测试的结果去调整设计和提示词,重新生成

这里的“提示词”充当的就是以前的“详细设计文档”的作用,但是可以简化许多,只要 AI 能看得懂就行,怎么写都可以。
这样的好处是大幅降低了从设计到代码的成本,并且重构调整起来也没有什么心理负担,不像以前,辛苦写的代码,是有些舍不得删的。另外你可以把更多精力花在系统设计上,更关注全局而不是代码实现。
当然采用这种模式开发,需要注意一次不要生成太多代码,不然就可能会失控。
除此之外,还需要在开发工具和流程上配合
首先你得有源代码管理,每次 AI 的变更都记录下来。
因为 AI 生成后的代码,很多时候我们不是继续修改,而是重新调整提示词,回滚后重新生成。AI 生成代码更多会变成像 AI 画图,不停的生成新版本,不满意调整提示词重新生成,或者换一个模型重新生成,而不是基于一个错误的结果反复 PUA AI 让它修改,因为一旦 AI 生成错了,那么错误的结果会影响到后续的生成,不要把它真的当成有智能的无所不能的生物,而是要把它看作一个概率生成工具,错误的结果会继续放大错误的概率。
记住一个原则:小错误才继续修复,稍微大一点错误直接回滚修改提示词或者换模型后重新生成,不要舍不得那点 Tokens,比起浪费的时间来不值钱。
**另外就是要 Review 代码和测试。 **
很多人没有 Review 代码的习惯,更没有测试自己代码的习惯,每次让 AI 生成代码,我都会仔细看一遍生成的结果,看代码和我期望的是不是一样的——如果我自己写,会怎么样写,它的方案是更好还是更早,更好我可以学习,也欣然接受;如果质量还凑合没那么好,但是也没大毛病,那就这样了也可以接受;不够好我就回滚调整提示词,或者追加一下要求。我们 Review AI 的代码也没必要吹毛求疵,大部分时候够用就好,要求可以适当低一点。
测试也很重要,单元测试这种用例是要自己设计自己review的,手工测试也必不可少,尽可能让测试成本降低,比如通过命令行去测试、测试代码去测试,这样每次生成完都可以马上测试马上验证,有问题就回滚或者修复。
对于新人来说,去适用 AI 编程反而比较容易,因为没有以前的经验依赖,但是对于有很多年编程经验的人,反而难以调整自己,使用 AI 编程浅尝则止,总会觉得 AI 太弱不如自己,建议还是需要一点耐心,给自己一点时间去适应,短期可能比较不习惯的,但是当你适应后,你会喜欢这样的开发方式,结果也会更好,甚至再难回到以前那种纯手工的模式。