被一个 shared 目录卡住后,我重新思考了 AI 时代的代码封装
从权限卡点到工程范式反思
上周,我启动一个新项目,准备用 AI 工具快速生成前后端代码。
一切都很顺利——直到我发现:项目依赖一个内部 shared/prisma/ 模块,而我没有访问权限。
申请权限要走流程,等审批可能要一天。
可讽刺的是——我用 Vibe Coding 这类 AI 工具,10 分钟就能写出一模一样的数据库访问层。
那一刻我意识到:在 AI 编程普及的今天,有些“封装”正在从助力变成阻力。
一、传统封装的逻辑:统一、复用、防错
在纯手工开发时代,封装是工程最佳实践的核心。
我们把数据库操作抽象成 ORM 层,把工具函数放进 shared/utils/,把认证逻辑抽成中间件——目的很明确:
- ✅ 减少重复代码
- ✅ 统一团队规范
- ✅ 降低人为错误
这些做法建立在一个前提上:开发者是人,而人会累、会忘、会写错。
所以,“封装 = 提效”几乎成了共识。
二、AI 编程时代,这个前提变了
如今,我用 AI 辅助开发,体验完全不同:
- AI 不怕“重复”:它能秒级生成标准化的 CRUD、Service、Controller。
- AI 怕“黑盒”:如果封装没有清晰类型、文档或调用示例,AI 无法理解,只能瞎猜甚至绕过。
- AI 追求“敏捷”:项目启动越快越好,强依赖外部模块反而拖慢节奏。
回到我的卡点:
那个 shared/prisma/ 模块,初衷可能是好的——统一 ORM 初始化、连接池配置等。
但它带来的问题也很现实:
- ❌ 新项目无法独立启动(权限壁垒)
- ❌ AI 无法理解其内部逻辑(缺乏类型/文档)
- ❌ 修改成本高(需协调维护者)
结果是:为了“复用几行初始化代码”,整个项目被卡住。
这还是“提效”吗?
三、AI 时代的封装,应该长什么样?
不是不要封装,而是要为 AI 友好而设计的封装。结合近期实践,我总结了几条原则:
✅ 1. 显式优于隐式
让逻辑“看得见”。例如,直接在项目中定义 prisma/schema.prisma,AI 能直接读取模型并生成对应代码。
避免再包一层“统一 DAO”,除非它导出完整 TypeScript 类型。
✅ 2. 自包含优于强耦合
每个项目应能独立运行。共享能力可通过以下方式提供:
- 私有 npm 包(如
@company/db-client) - 脚手架模板(如
create-company-app) - Git Submodule(谨慎使用)
关键:非强制依赖,按需引入。
✅ 3. 类型驱动,而非约定驱动
AI 依赖结构化元数据。确保任何共享模块:
- 导出完整的
.d.ts类型 - 提供调用示例(最好带 JSDoc)
- 避免动态 require 或魔法字符串
✅ 4. 可生成 > 可复用
过去追求“一次编写,处处复用”;现在更应追求“按需生成,处处一致”。
AI 能保证不同项目中的相似逻辑高度一致,无需靠共享库“强制统一”。
四、我的新项目实践
基于以上思考,我现在的新项目结构如下:
my-new-project/
├── prisma/
│ ├── schema.prisma ← 显式定义模型
│ └── client.ts ← 导出 PrismaClient(带类型)
├── src/
│ ├── services/
│ └── controllers/
├── package.json
└── README.md ← 包含 AI 友好说明
- 不依赖任何外部
shared/目录 - 所有数据库逻辑自包含
- AI 工具可直接理解并扩展
项目从 0 到可运行,仅用 15 分钟。
五、结语:封装是手段,不是目的
封装本身没有错。
错的是——用旧时代的封装逻辑,去约束新时代的开发范式。
当 AI 成为我们的编程伙伴,工程体系也该进化:
从“防人犯错”转向“助 AI 协同”,
从“强管控”转向“高敏捷”。
也许未来判断一个项目是否“现代化”,不再看它有没有 shared/ 目录,
而是看:AI 能不能在 5 分钟内读懂它,并开始写代码?
你在用 AI 编程时,是否也被“封装”绊住过?
欢迎在评论区分享你的经历,一起探索更高效的 AI 原生开发模式!
更多推荐



所有评论(0)