"Make it work, make it right, make it fast." — Kent Beck
上一篇说过,jsbench 的第一版基本是 AI 写的。能跑,测试也过了。"Make it work",AI 已经做到了。
但 "make it right" 呢?这正是我接下来要做的事——重构架构。
其实做这个项目的时候,我有两个选择:一是提前把架构跟 AI 讲清楚,让它按我的标准来;二是先让 AI 自由发挥,生成一个能用的版本,然后我再重构。
我选了后者。原因很简单:我想看看 AI 独立做出来的东西到底长什么样。 哪些地方它做得好,哪些地方不够好——不亲自看一遍,心里没数。这本身也是一种学习。重构的过程,就是我跟 AI 代码对话的过程。
为什么是架构
上一篇我说过,架构是 AI 目前最明显的短板。但换个角度想,这恰恰说明了一件事:如果架构做好了,剩下的业务代码对 AI 来说都很简单。
想想看,AI 已经能写出正确的函数、合理的命名、完整的测试。它欠缺的是什么?是代码怎么组织、模块怎么拆、抽象放在哪一层。
这意味着,在 AI 时代,架构的价值被放大了。以前架构好不好,影响的是团队协作效率和维护成本。现在架构好不好,直接决定了你能不能高效地用 AI 来写代码。
架构对了,AI 就是你的整个团队。架构不对,AI 写再多代码也是在堆技术债。
所以这个系列的主线就是重构架构。每次改一个点,每次都有明确的理由。
第一刀:代码组织
架构的第一步不是什么高深的设计模式,而是最基础的东西——文件怎么命名,代码怎么组织,构建产物放在哪。
这些决策看似琐碎,但它们定义了项目的"骨架"。后续所有的模块拆分、依赖管理、接口设计,都建立在这个骨架之上。
AI 做得其实不错
先说公道话。AI 生成的代码有一个好习惯:所有函数和类型都用了 jsb_ 前缀。
jsb_conn_t *jsb_conn_create(...);
void jsb_conn_free(jsb_conn_t *c);
int jsb_http_response_feed(jsb_http_response_t *r, ...);
C 语言没有命名空间,用前缀避免冲突是标准做法。AI 知道这一点,而且执行得很一致——13 个源文件,上百个函数和类型,前缀没有一处遗漏。这个纪律性,说实话比很多人类项目都好。
文件命名也合理:http_client.c、http_parser.c、event_loop.c,见名知意。
所以不是说 AI 做得差。是我要按自己的标准来——这些标准来自多年在 nginx 团队写 C 代码的经验。
改动一:代码前缀 jsb_ → js_
jsb 是 "jsbench" 的缩写,AI 的选择完全合理。但我更偏好 js_——更短,跟项目的核心身份(JS runtime)更贴合。在 nginx 生态里,前缀都是简短的项目缩写:ngx_、njs_。
// before
jsb_conn_t *jsb_conn_create(...);
// after
js_conn_t *js_conn_create(...);
改动二:文件名统一加 js_ 前缀
// before
src/main.c
src/http_client.c
src/http_parser.c
src/jsb.h
// after
src/js_main.c
src/js_http_client.c
src/js_http_parser.c
src/js_main.h
在 nginx 和 njs 项目中,每个文件都带项目前缀。好处很实际:在一个大的工作目录下搜索文件时,前缀能帮你快速定位属于哪个项目。
改动三:构建产物分离
AI 把 .o 文件直接生成在 src/ 目录里——源码和编译产物混在一起。改成统一输出到 build/,src/ 只留纯源码。
// before
src/main.c
src/main.o ← 混在一起
// after
src/js_main.c
build/js_main.o ← 分离
代码是给人看的
这些改动不影响功能,不影响性能。测试跑完还是 14 个全过。
但代码不只是给机器执行的,代码是给人看的。命名风格、文件组织、目录结构——都是在降低人类理解代码的成本。
AI 不需要这些。a.c、b.c、x_func_1——对 AI 来说没有区别。但对人来说有区别。
上一篇我说过,AI 的审美和人类不一样。这就是一个具体的例子。AI 的选择没有错,但我有自己的标准——来自在 nginx 团队写了多年 C 代码的经验。
不过我相信,命名和代码组织这件事,AI 将来一定能做得很好。只要给它足够的上下文——"参考 nginx 的命名风格"——它大概率能生成完全符合你期望的代码。这次我没有给它这个上下文,所以它按自己的判断来了。判断不差,只是不完全是我想要的。
下一步
骨架理好了,接下来进入真正的模块设计。
GitHub: github.com/hongzhidao/…
本文对应的代码变更: 559a644
更多文章和后续更新,关注微信公众号:程序员洪志道