文章目录
-
- 🌌 前言
- 🎬 第一幕:打开项目的那一刻,我傻了
- 🕵️ 第二幕:这真的是 AI 写的?
-
- 📚 文档比代码还认真
- 🏗️ 架构居然是对的
- 🧹 技术还债,AI 比我还积极
-
- 🔹 第一步:重复代码抽取
- 🔹 第二步:错误处理统一
- 🔹 第三步:巨型函数拆分
- 🔹 第四步:魔法数字 + 硬编码颜色
- 🔹 第五步:V1→V2 状态管理迁移
- 🎮 第三幕:功能居然还挺香
-
- 🎭 AI 角色扮演引擎
- 📖 互动小说
- 💬 聊天体验
- 🌙 细节到位
- 🤔 第四幕:所以… Vibe Coding 到底是什么?
- 💡 我的真实感受:AI 学得比谁都快
- 🎯 结尾:AI 时代,程序员的新角色
- 📊 项目数据小结
✍️ 作者:雨雨 📅 发布时间:2026-06-18 🏷️ 标签:#鸿蒙开发 #AI编程 #DeepSeek #ArkTS #VibeCoding
🌌 前言
三个月前,我决定整个活儿。
搞一个 AI 角色扮演聊天 App,鸿蒙原生,对接 DeepSeek。想法很简单:AI 写代码,我当产品经理。
什么架构、什么规范、什么文档——那都是正经项目才有的东西。
我就是来 Vibe Coding 的。
🎬 第一幕:打开项目的那一刻,我傻了
今天准备写篇「垃圾代码鉴赏」,标题都想好了,就叫《Vibe Coding 大赏》。
我打开项目文件夹,准备截几张屎山代码图,然后开始吐槽:
RPChat/
├── 📂 官方API查询记录/ # 这啥?
├── 📂 docs/
│ └── 📂 superpowers/
│ ├── 📂 plans/ # 还有计划?
│ └── 📂 specs/ # 还有设计文档?
├── 📄 ARCHITECTURE.md # 650 行架构文档?
├── 📄 TECH_DEBT.md # 技术债务追踪?
├── 📄 CHANGELOG.md # 变更日志?
└── 📄 README.md # 这个倒是很正常
等等,Vibe Coding 项目怎么会有技术债务文档?
我点开 TECH_DEBT.md,第一行是:
📌 最后更新:2026-06-04(全部技术债已清 + v3.6 小说流式输出已完成)
然后是一张表格:
| 第一步 | 重复代码抽取 | 低 | ✅ 已完成 |
| 第二步 | 错误处理统一 | 低 | ✅ 已完成 |
| 第三步 | 巨型函数拆分 | 中 | ✅ 已完成 |
| 第四步 | 魔法数字 + 硬编码颜色 | 低 | ✅ 已完成 |
| 第五步 | V1→V2 状态管理迁移 | 高 | ✅ 已完成 |
全清了???
我预想的「屎山代码鉴赏」,刚开场就翻车了。 🫠
🕵️ 第二幕:这真的是 AI 写的?
我硬着头皮继续翻,越翻越离谱。
📚 文档比代码还认真
ARCHITECTURE.md,650 行,内容包括:
- ✅ 分层架构图(5 层:Model/Database → Repository → Service → ViewModel → Page)
- ✅ 10 张数据库表的完整字段设计
- ✅ 9 个 Repository 的接口定义
- ✅ 10 个 Service 的职责划分
- ✅ 5 个 ViewModel 的状态管理说明
- ✅ 11 个页面的导航流程图
- ✅ 深色模式与沉浸式布局实现方案
- ✅ ArkTS 兼容性踩坑表(13 个坑 + 解决方案)
- ✅ 错误处理策略
甚至还有一个专门的文件夹 「官方API查询记录」,记录了每一个技术决策前查的官方文档:
官方API查询记录/
├── 📄 Hilog日志采集方案.md
├── 📄 技术还债-重复代码抽取.md
├── 📄 AI输出思考内容解决方案.md
├── 📄 技术还债-巨型函数拆分.md
├── 📄 技术还债-魔法数字+硬编码颜色.md
├── 📄 技术还债-V1至V2迁移.md
├── 📄 AI调用清单.md
├── 📄 流式输出与思考内容显示方案.md
├── 📄 RCP流式请求方案.md
├── 📄 Scroll条件渲染自动滚动解决方案.md
└── 📄 AI流式输出后自动跳回输出位置解决方案.md
🤯 灵魂拷问:AI 写代码还查官方文档?
🏗️ 架构居然是对的
┌─────────────────────────────────┐
│ Pages(UI 层) │ ← ArkUI 声明式组件
├─────────────────────────────────┤
│ ViewModel(视图模型层) │ ← @ObservedV2 + @Trace
├─────────────────────────────────┤
│ Service + Repository(业务层) │ ← API 调用 + 数据访问
├─────────────────────────────────┤
│ Model + Database(数据层) │ ← 实体定义 + SQLite
└─────────────────────────────────┘
经典的分层架构,每层职责清晰。Repository 模式封装数据访问,Service 层抽象业务逻辑,ViewModel 管理状态,Page 纯渲染。
甚至还有 Prefix Caching 优化:System Prompt 放在 messages[0],内容不变时 DeepSeek 服务端自动缓存,延迟从 3s 降到 1s。
💭 内心 OS:AI 连这个都懂?
🧹 技术还债,AI 比我还积极
TECH_DEBT.md 里记录的还债细节,看得我头皮发麻:
🔹 第一步:重复代码抽取
- 4 处级联删除逻辑统一到 ViewModel,加 RDB 事务
- 2 个页面各 300 行的设定更新流程,抽取成共享 Service
- 3 处删除确认弹窗统一封装,顺便把废弃的 AlertDialog.show() 全换成了 UIContext.showAlertDialog()
- 2 处 AI 生成流程用泛型函数统一
🔹 第二步:错误处理统一
- 补了 14 处静默 catch 的 hilog.warn 日志
- 17 处错误信息格式统一
- 事务 rollback 全部加了错误处理
🔹 第三步:巨型函数拆分
- NovelReadPage.build() 908 行 → 拆出 12 个 @Builder,剩 25 行
- ChatPage.build() 478 行 → 拆出 8 个 @Builder,剩 18 行
- sendMessage() 133 行 → 拆成 6 个小函数,群聊改用 Promise.allSettled
🔹 第四步:魔法数字 + 硬编码颜色
- 14 个魔法数字全部提取为命名常量
- 16 处硬编码颜色全部改为 $r('app.color.xxx') 资源引用
🔹 第五步:V1→V2 状态管理迁移
- 全项目 11 个页面从 @Component + @State 迁移到 @ComponentV2 + @Local
- 删除 syncState() 手动逐字段拷贝(~140 行)
- 删除 pollSync() setInterval 轮询反模式
- 全部 7 个数据模型加 @ObservedV2 + @Trace
✅ 每一步都有调研、有方案、有风险评估、有修改文件清单、有验证通过标记。
这哪里是 Vibe Coding,这是 Jira Ticket Coding。 😂
🎮 第三幕:功能居然还挺香
吐槽归吐槽,这个 App 做的东西是真的香:
🎭 AI 角色扮演引擎
- 世界观 + 角色设定 + 个人设定三方拼接 System Prompt
- 支持自定义头像(Emoji)、性格、背景、说话风格
- DeepSeek 思考模式 + 推理过程实时显示
📖 互动小说
- 多角色同场对话,AI 自动分配戏份
- RCP SSE 真流式输出,边写边看
- 自动摘要 + 手动调整剧情走向
- 字号/行距自定义 + 阅读位置自动记忆
💬 聊天体验
- Markdown 富文本渲染(代码块、列表、表格全支持)
- 对话历史自动保存 + 中断后继续
- 相对时间标签(刚刚 / 5 分钟前 / 昨天)
- TXT / JSON 双格式导出
🌙 细节到位
- 跟随系统深色模式自动切换
- 22 组语义化颜色资源
- 沉浸式全屏布局,状态栏导航栏自动避让
- 全部操作加事务、加 try/catch、加日志
🤔 第四幕:所以… Vibe Coding 到底是什么?
写这篇博客的时候我一直在想:我本来想吐槽 Vibe Coding,结果写着写着变成了「优秀项目鉴赏」。
那到底什么是 Vibe Coding?
以前我以为:
❌ Vibe Coding = 凭感觉瞎写,能跑就行,不管质量
但现在我觉得:
✅ Vibe Coding = 用 AI 把你的工程直觉快速变成现实
AI 帮你写业务逻辑、写 CRUD、写组件——这些都是体力活。但真正决定代码质量的,是你的"感觉":
| 🧠 这个地方有重复代码,得抽成 Service | ⭐⭐⭐ |
| 🧠 这个 catch 里什么都不写,以后肯定要踩坑 | ⭐⭐⭐⭐ |
| 🧠 这个函数 100 多行,得拆一下 | ⭐⭐⭐ |
| 🧠 这个颜色硬编码在这里,深色模式要出问题 | ⭐⭐ |
| 🧠 这里用轮询同步状态,太蠢了,得用响应式 | ⭐⭐⭐⭐ |
这些"感觉",AI 没有。
AI 可以写出 100% 正确的代码,但它不会主动问:
- “要不要我把这三处重复逻辑抽一下?”
- “这个静默吞错误的地方要不要加个日志?”
- “这几个魔法数字要不要定义成常量?”
这些,就是人类工程师的 Vibe。
💡 我的真实感受:AI 学得比谁都快
说到这里,必须分享一下我这三个月最深刻的体会:
🚀 用 AI 编程最大的感受,不是 AI 什么都会,而是 AI 学得非常快。
这个项目里,踩了无数鸿蒙 ArkTS 的坑:
- Date.now() 在严格模式下被禁用,查了官方文档才知道要用 systemDateTime.getTime()
- AlertDialog.show() 从 API 18 起废弃了,要用 UIContext.showAlertDialog()
- @ComponentV2 必须配合 @Local,不能用 @State
- RCP 流式请求的回调签名,网上完全找不到示例
每次遇到这种无解的 bug,我的流程是:
#mermaid-svg-z0Dirp2kVgKM5NFL{font-family:\”trebuchet ms\”,verdana,arial,sans-serif;font-size:16px;fill:#333;}@keyframes edge-animation-frame{from{stroke-dashoffset:0;}}@keyframes dash{to{stroke-dashoffset:0;}}#mermaid-svg-z0Dirp2kVgKM5NFL .edge-animation-slow{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 50s linear infinite;stroke-linecap:round;}#mermaid-svg-z0Dirp2kVgKM5NFL .edge-animation-fast{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 20s linear infinite;stroke-linecap:round;}#mermaid-svg-z0Dirp2kVgKM5NFL .error-icon{fill:#552222;}#mermaid-svg-z0Dirp2kVgKM5NFL .error-text{fill:#552222;stroke:#552222;}#mermaid-svg-z0Dirp2kVgKM5NFL .edge-thickness-normal{stroke-width:1px;}#mermaid-svg-z0Dirp2kVgKM5NFL .edge-thickness-thick{stroke-width:3.5px;}#mermaid-svg-z0Dirp2kVgKM5NFL .edge-pattern-solid{stroke-dasharray:0;}#mermaid-svg-z0Dirp2kVgKM5NFL .edge-thickness-invisible{stroke-width:0;fill:none;}#mermaid-svg-z0Dirp2kVgKM5NFL .edge-pattern-dashed{stroke-dasharray:3;}#mermaid-svg-z0Dirp2kVgKM5NFL .edge-pattern-dotted{stroke-dasharray:2;}#mermaid-svg-z0Dirp2kVgKM5NFL .marker{fill:#333333;stroke:#333333;}#mermaid-svg-z0Dirp2kVgKM5NFL .marker.cross{stroke:#333333;}#mermaid-svg-z0Dirp2kVgKM5NFL svg{font-family:\”trebuchet ms\”,verdana,arial,sans-serif;font-size:16px;}#mermaid-svg-z0Dirp2kVgKM5NFL p{margin:0;}#mermaid-svg-z0Dirp2kVgKM5NFL .label{font-family:\”trebuchet ms\”,verdana,arial,sans-serif;color:#333;}#mermaid-svg-z0Dirp2kVgKM5NFL .cluster-label text{fill:#333;}#mermaid-svg-z0Dirp2kVgKM5NFL .cluster-label span{color:#333;}#mermaid-svg-z0Dirp2kVgKM5NFL .cluster-label span p{background-color:transparent;}#mermaid-svg-z0Dirp2kVgKM5NFL .label text,#mermaid-svg-z0Dirp2kVgKM5NFL span{fill:#333;color:#333;}#mermaid-svg-z0Dirp2kVgKM5NFL .node rect,#mermaid-svg-z0Dirp2kVgKM5NFL .node circle,#mermaid-svg-z0Dirp2kVgKM5NFL .node ellipse,#mermaid-svg-z0Dirp2kVgKM5NFL .node polygon,#mermaid-svg-z0Dirp2kVgKM5NFL .node path{fill:#ECECFF;stroke:#9370DB;stroke-width:1px;}#mermaid-svg-z0Dirp2kVgKM5NFL .rough-node .label text,#mermaid-svg-z0Dirp2kVgKM5NFL .node .label text,#mermaid-svg-z0Dirp2kVgKM5NFL .image-shape .label,#mermaid-svg-z0Dirp2kVgKM5NFL .icon-shape .label{text-anchor:middle;}#mermaid-svg-z0Dirp2kVgKM5NFL .node .katex path{fill:#000;stroke:#000;stroke-width:1px;}#mermaid-svg-z0Dirp2kVgKM5NFL .rough-node .label,#mermaid-svg-z0Dirp2kVgKM5NFL .node .label,#mermaid-svg-z0Dirp2kVgKM5NFL .image-shape .label,#mermaid-svg-z0Dirp2kVgKM5NFL .icon-shape .label{text-align:center;}#mermaid-svg-z0Dirp2kVgKM5NFL .node.clickable{cursor:pointer;}#mermaid-svg-z0Dirp2kVgKM5NFL .root .anchor path{fill:#333333!important;stroke-width:0;stroke:#333333;}#mermaid-svg-z0Dirp2kVgKM5NFL .arrowheadPath{fill:#333333;}#mermaid-svg-z0Dirp2kVgKM5NFL .edgePath .path{stroke:#333333;stroke-width:2.0px;}#mermaid-svg-z0Dirp2kVgKM5NFL .flowchart-link{stroke:#333333;fill:none;}#mermaid-svg-z0Dirp2kVgKM5NFL .edgeLabel{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-z0Dirp2kVgKM5NFL .edgeLabel p{background-color:rgba(232,232,232, 0.8);}#mermaid-svg-z0Dirp2kVgKM5NFL .edgeLabel rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-z0Dirp2kVgKM5NFL .labelBkg{background-color:rgba(232, 232, 232, 0.5);}#mermaid-svg-z0Dirp2kVgKM5NFL .cluster rect{fill:#ffffde;stroke:#aaaa33;stroke-width:1px;}#mermaid-svg-z0Dirp2kVgKM5NFL .cluster text{fill:#333;}#mermaid-svg-z0Dirp2kVgKM5NFL .cluster span{color:#333;}#mermaid-svg-z0Dirp2kVgKM5NFL div.mermaidTooltip{position:absolute;text-align:center;max-width:200px;padding:2px;font-family:\”trebuchet ms\”,verdana,arial,sans-serif;font-size:12px;background:hsl(80, 100%, 96.2745098039%);border:1px solid #aaaa33;border-radius:2px;pointer-events:none;z-index:100;}#mermaid-svg-z0Dirp2kVgKM5NFL .flowchartTitleText{text-anchor:middle;font-size:18px;fill:#333;}#mermaid-svg-z0Dirp2kVgKM5NFL rect.text{fill:none;stroke-width:0;}#mermaid-svg-z0Dirp2kVgKM5NFL .icon-shape,#mermaid-svg-z0Dirp2kVgKM5NFL .image-shape{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-z0Dirp2kVgKM5NFL .icon-shape p,#mermaid-svg-z0Dirp2kVgKM5NFL .image-shape p{background-color:rgba(232,232,232, 0.8);padding:2px;}#mermaid-svg-z0Dirp2kVgKM5NFL .icon-shape .label rect,#mermaid-svg-z0Dirp2kVgKM5NFL .image-shape .label rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-z0Dirp2kVgKM5NFL .label-icon{display:inline-block;height:1em;overflow:visible;vertical-align:-0.125em;}#mermaid-svg-z0Dirp2kVgKM5NFL .node .label-icon path{fill:currentColor;stroke:revert;stroke-width:revert;}#mermaid-svg-z0Dirp2kVgKM5NFL :root{–mermaid-font-family:\”trebuchet ms\”,verdana,arial,sans-serif;}
AI 写了一版
编译报错
AI 自己瞎改了三版
还是报错
我去翻鸿蒙官方文档查半小时
找到正确写法
把官方文档+报错喂给 AI
AI 瞬间就懂了 → 下一版直接写对
就是这么一个非常冷门的 API,AI 一次就学会了,下次遇到类似问题直接就会用了。
人类查文档的 30 分钟 + AI 学习的 10 秒钟 = 问题解决。
这种效率,真的恐怖。 🚀
🎯 结尾:AI 时代,程序员的新角色
这个项目 99% 的代码是 AI 写的,但剩下 1% 是最关键的:
| 架构设计 —— 告诉 AI 分成 5 层,每层干什么 | 0.25% | 👨💻 我 |
| 代码审查 —— 挑出 AI 写的 14 处静默 catch、N 处重复代码 | 0.25% | 👨💻 我 |
| 技术债务管理 —— 识别、计划、偿还 | 0.25% | 👨💻 我 |
| 踩坑记录 —— 查官方文档、记下来、避免下次再踩 | 0.25% | 👨💻 我 |
| 业务代码、组件、CRUD | 99% | 🤖 AI |
以前程序员的工作是:
写代码 → 改 bug → 写文档
以后程序员的工作是:
告诉 AI 写什么 → 审查 AI 写的代码 → 重构 AI 制造的技术债务 → 写文档
我们从 Coder,变成了 Tech Lead of AI。
这或许就是 Vibe Coding 的终极形态:
✨ 你不用再亲手敲每一行代码,但你对代码质量的直觉,比任何时候都重要。
毕竟,AI 写的代码再快,没有那个"感觉"—— 它永远只是一坨能跑的代码而已。
📌 温馨提示: 本项目所有技术债务已还清。 想骂屎山的,下次一定。 😂
📊 项目数据小结
| 数据模型 | 7 个 |
| 数据库表 | 10 张 |
| Repository | 9 个 |
| Service | 10 个 |
| ViewModel | 5 个 |
| UI 页面 | 11 个 |
| 偿还技术债务 | 5 大步(全部完成) |
| 官方 API 调研记录 | 11 份 |
| 架构文档 | 650 行 |
💬 如果这篇文章对你有启发,欢迎点赞 👍 收藏 ⭐ 评论 💬 三连支持!



