主题
界面
主题
从 S0 到 S3,我们一直在写代码;本节抬头看**"代码是怎么被组织成产品的"**:
个人写代码:能跑就行
团队做产品:能跑 + 能改 + 能协作 + 能上线 + 能回滚★ S4 之后的六节(本节 + SOLID + 三种设计模式 + Spring 中的应用)讲"设计"; 再往后的 Redis、MQ、微服务讲"技术选型" ✓
先看三个"技术很好但项目失败"的典型 ✗:
| 现象 | 真正的病因 |
|---|---|
| 功能都实现了,但改一个需求要两周 ✗ | 复杂度失控(没有边界、没有抽象) |
| 上线前一周天天加班,上线后天天修 bug ✗ | 流程缺失(没测试、没灰度、没回滚) |
| 三个人改同一个文件,每次合并都冲突 ✗ | 协作问题(没有模块边界与接口约定) |
★ 这三个都不是"技术问题",但都会以技术问题的形式暴露 ✓✓
软件工程的核心命题 ✓:
让"更多人、更长时间"地维护一份代码,仍然保持可控 ✓
| # | 敌人 | 表现 | 主要手段 |
|---|---|---|---|
| ① | 复杂度 ★★★ | 改一处崩三处;新人上手要一个月 | 模块化、抽象、分层(《SOLID 原则》 ~ 《设计模式在 Spring 中的应用》)✓ |
| ② | 变化 ★★★ | 需求总在变,代码改不动 | 开闭原则、扩展点、配置化 ✓ |
| ③ | 沟通 ★★ | 接口对不齐、重复劳动、互相等待 | 接口先行、文档、评审 ✓ |
★ 一条重要认识 ✓✓:
代码的"可维护性"不是审美,而是经济性** ——** 它决定了"下一次改需求要花多少钱" ✓
SOLID 与设计模式的价值,全部在这个账本里 ✓✓
| 阶段 | 核心特点 | 解决的问题 | 遗留的问题 |
|---|---|---|---|
| 瀑布 ✗ | 需求 → 设计 → 开发 → 测试 → 上线,逐阶段推进 | 有章法、可计划 ✓ | 反馈太晚(上线才知道错)✗✗ |
| 敏捷 ★★ | 小步快跑、两周一个迭代、持续反馈 | 缩短反馈周期 ✓✓ | 工程实践容易跟不上(只学了"站会")⚠️ |
| DevOps ★★★ | 开发与运维一体化 + 自动化流水线 | 把"交付"也变成自动化 ✓✓ | 需要文化与工具支撑 ⚠️ |
★ "敏捷"最容易被误解的一点 ✓✓:
敏捷不是"不写文档、不做设计、随时改需求" ✗✗
它恰恰要求"工程实践更严格" —— 因为迭代快,所以必须靠"自动化测试 + 持续集成"来接住 ✓✓
★ 本项目的形态就是一个"微型 DevOps" ✓:
写代码 → 本地流水线(L1 校验 / L2 快测试 / L3 慢测试)→ 构建站点 → 提交打标签
↑ 每一步都是自动化的,且"失败即停"| 环节 | 关键实践 | 常见坑 |
|---|---|---|
| 需求 ★★ | 明确"不做什么"、可验收的验收标准 | 需求模糊 → 反复返工 ✗ |
| 设计 ★★★ | 接口先行(先定契约,再并行开发) | 一个人拍脑袋定接口,别人被动适配 ✗ |
| 开发 ★★ | 小步提交、提交信息规范、分支短命 | 一个分支活两周 → 合并地狱 ✗✗ |
| 评审 ★★★ | 看设计而非格式、控制在 400 行内 | 1000 行的 PR 没人认真看 ✗ |
| 测试 ★★★ | 测试分层(单元多、UI 少) | 全靠手工回归 → 越到后面越不敢发 ✗ |
| 发布 ★★★ | 灰度 + 可回滚 + 可观测 | 一次性全量发 ✗✗ |
| 运维 ★★ | 告警 + 日志 + 指标(《日志框架与日志规范》) | 出问题只能靠用户反馈 ✗ |
★ 其中"接口先行"与"小步提交"的收益最直接 ✓✓:
| 实践 | 收益 |
|---|---|
| 接口先行 ★★★ | 前后端/上下游可以并行开发(不用互相等)✓✓ |
| 小步提交 ★★ | 每次改动小 → 评审快、回滚容易、冲突少 ✓✓ |
★ 反面案例(很常见) ✗:
一个分支开发两周 → 攒了 80 个文件改动 → 评审只能"看着差不多就合" → 出事 → 回滚要回滚两周的量 ✗✗★ 所以有一条硬建议 ✓✓:
一个 PR 一件事,改动控制在几百行以内 ✓
做不到就说明"任务拆得不够细" ✓
评审的注意力分配(按重要性) ✓✓:
| 优先级 | 看什么 | 例子 |
|---|---|---|
| ① | 正确性 ★★★ | 边界条件、空值、并发、事务边界 |
| ② | 设计与抽象 ★★★ | 这段逻辑该放这里吗?依赖方向对吗? |
| ③ | 可测试性 ★★ | 能不能不连数据库就测? |
| ④ | 可读性 ★★ | 命名、注释(解释"为什么"而非"做了什么") |
| ⑤ | 格式 ⚠️ | 交给工具(Spotless / Checkstyle),不要靠人眼 ✗ |
★ 最后一条特别重要 ✓✓:
格式问题应该由工具自动检查并自动修复 ✓
让人在评审里讨论缩进和空格,是在浪费两份薪水 ✗✗
★ 评审的另一个隐性收益 ✓:
它是团队知识扩散的主要渠道 —— 比"写文档让人看"有效得多 ✓✓
技术债的两种形态 ✓:
| 形态 | 特征 | 处理 |
|---|---|---|
| 有意借的 ★ | 为了赶上线先简化,且记了 TODO 与偿还计划 | 可接受,但要排期偿还 ✓ |
| 无意欠的 ✗✗ | 因为不懂而写错(如把配置写死、没做隔离) | 必须还 ——它会持续产生利息 ✓✓ |
★ "利息"长什么样 ✓:
一处硬编码的连接串 → 每次换环境都要改代码 → 每次发布多 30 分钟
一个没抽接口的依赖 → 想加单元测试却发现必须连数据库 → 测试永远写不起来★ 一条务实的判断 ✓✓:
技术债的偿还优先级 = "它阻碍了多少后续工作" ✓
不阻碍的债可以放着;阻碍所有人每天工作的债要立刻还 ✓✓
本项目其实已经把工程实践都跑过一遍了 ✓ ——只是之前分散在各处:
| 实践 | 本项目在哪讲过 |
|---|---|
| Git 分支与提交规范 | 《Git 基础与 cherry-pick》 ✓ |
| Maven 依赖与模块化 | 《事务与隔离级别》 ✓ |
| 单元 / 切片 / 集成 / UI 测试分层 | T1-016、T1-017、T2-012 ✓ |
| CI 分层执行与报告归档 | T2-004、T2-017 ✓ |
| 接口设计与文档 | 《Spring MVC 请求映射与参数绑定》、《接口文档与前后端联调》 ✓ |
| 日志、指标、traceId | 《日志框架与日志规范》 ✓ |
| 部署与进程管理 | 《Linux 服务部署与运维》 ✓ |
★ 本节的作用是把这些串起来 ✓ ——它们不是零散技巧,而是同一套工程方法 ✓✓
feat: 新增订单导出接口
← 空行分隔标题与正文
- 支持按时间范围筛选
- 导出为 CSV,单次上限 1 万条(超出提示分批)
- 补充接口文档与 3 个单元测试★ 三行正文回答了"改了什么、边界在哪、怎么验证" ✓
✗ 一个人做完"订单模块"再做"用户模块" → 串行,且合并时冲突多 ✗
✓ 先定接口(OrderService / UserService 的方法签名)→ 两人并行开发 → 各自提交 ✓✓"这次太急,就不写测试了、直接发到生产"
→ 出问题 → 只能靠回滚 → 更慢 ✗✗本节无新增代码 ——它的"实测"就是本项目自己的流水线数据 ✓
===== 流水线结果 =====
L1 登记表与结构校验 2.3 秒 通过
L2 快速单元测试(13 个模块) 25 秒 通过
L3 慢测试(Spring 模块) 34.5 秒 通过
合计 61.8 秒★ 这 61.8 秒换来了什么 ✓:
| 收益 | 说明 |
|---|---|
| 每次改动都被自动验证 ★★ | 不用靠人记得"跑一遍测试" ✓ |
| 失败即停 | 早失败早发现,不浪费时间 ✓ |
| 报告归档 | 出问题能回溯到具体是哪个类的哪个方法 ✓ |
★ 对比"没有流水线"的代价 ✓ —— 本项目在 T2-004 实测过: 一次漏测的改动(pom 里少一行 parent)让 L2 直接失败,而流水线在 22 秒内就报了出来 ✓✓
| # | 错误 | 说明 |
|---|---|---|
| 1 | 把"敏捷"理解为"不做设计" ✗✗ | 敏捷要求更严格的工程实践(5.2)✗ |
| 2 | 一个 PR 攒两周的改动 ✗✗ | 无法认真评审、无法安全回滚 ✓ |
| 3 | 在评审里讨论格式 ✗ | 应该交给工具 ✓ |
| 4 | 接口不定就开工 ✗✗ | 上线前才发现对不齐 ✓ |
| 5 | 技术债只借不还 ✗✗ | 利息会越滚越大 ✓ |
| 6 | "紧急"成为跳过测试的常态 ✗✗ | 越紧急越要自动化 ✓✓ |
| 7 | 没有回滚方案就上线 ✗✗ | 出事只能靠改代码救火 ✓ |
目标:用"可度量"的方式检查一个项目的工程健康度。
步骤:
验收方式:能说出"你这个项目最该先还的那笔技术债是什么"。
扩展任务:给项目设计一条最小可用的流水线:
提交历史:
a1b2c3 fix
d4e5f6 update
g7h8i9 提交本次所有改动(含 87 个文件)这样的历史有什么问题? 5. (设计)给"订单导出"这个需求写一份接口先行的契约(方法签名 + 入参校验规则 + 返回结构 + 错误码)。
《SOLID 原则》:把"可维护性"变成五条可执行的设计规则。
无,可直接开始
暂无