img

📖 引言

2026年7月17日下午,"奇妙科学乐园"项目组召开了一次全员复盘会议。参会人员包括产品经理(PM)、设计师(UED)、架构师、前端开发(FE)、后端开发(BE)和测试工程师(QA),会议由架构师主持。这次复盘不是例行公事的"走过场",而是一场真刀真枪的"问题清算"——会议产出了16个具体问题,每个问题都追溯到了根本原因,并由此诞生了一套新的强制流程规范。

本文将以这次复盘会议的真实产出为基础,系统讲解项目复盘的方法论。复盘不是"追责大会",而是"找根因、定规则、防再犯"的系统性工程。我们将逐条分析16个问题的根因、应对措施和后续强制流程,帮助你理解如何将一次痛苦的开发经历转化为团队的宝贵资产。


🎯 学习目标

完成本文后,你将能够:

  • ✅ 掌握"现象-根因-措施"三维分析法进行问题根因追溯
  • ✅ 理解16个典型HarmonyOS开发问题的根本原因和应对方案
  • ✅ 学会设计强制性的开发流程规范,防止同类问题再次发生
  • ✅ 建立角色长效规则,让每个角色明确自己的职责边界
  • ✅ 将复盘产出物落地为可执行的行动项,而非停留在文档层面

💡 需求分析

复盘方法论框架

"奇妙科学乐园"复盘方法论
  │
  ├─ 第一步: 问题清单(发生了什么?)
  │    ├─ 全员参与,每个角色列出遇到的问题
  │    ├─ 按严重程度分级(🔴严重/🟡中等/🟢轻微)
  │    └─ 标注涉及角色(PM/UED/架构/FE/BE/QA)
  │
  ├─ 第二步: 根因分析(为什么会发生?)
  │    ├─ 逐条追溯根本原因(不是表面原因)
  │    ├─ 归类问题类别(技术/流程/协作/规范)
  │    └─ 使用"5个为什么"深挖根因
  │
  ├─ 第三步: 强制流程(如何防止再犯?)
  │    ├─ 按角色制定强制流程规范
  │    ├─ 流程必须可量化、可检查、可执行
  │    └─ 新流程纳入角色长效规则
  │
  └─ 第四步: 行动项跟踪(谁来执行?什么时候完成?)
       ├─ 每条措施指定负责人和截止时间
       ├─ 按优先级排序(P0/P1/P2)
       └─ 下次迭代启动前确认所有P0项已完成

16个问题分类统计

按严重程度分布:
  🔴 严重(6个): P01-P06 → 必须在下次迭代前解决
  🟡 中等(4个): P07-P10 → 必须在下次迭代M2前解决
  🟢 轻微(6个): P11-P16 → 尽快解决,不阻塞发布

按涉及角色分布:
  FE(前端): 12次 → 最频繁涉及的角色
  UED(设计): 5次 → 设计交付流程需要改进
  架构师: 4次 → 技术预研和环境评估不足
  PM(产品): 2次 → 需求管理流程需要规范
  QA(测试): 3次 → 测试覆盖和流程需要完善
  BE(后端): 2次 → 数据模型和Mock管理需要规范

按问题类别分布:
  技术预研缺失: 3个
  协作流程缺失: 4个
  编码规范问题: 3个
  设计规范不完整: 3个
  测试流程缺失: 3个

功能模块设计

模块 功能描述 技术要点
问题清单 16个问题的详细描述和严重程度分级 编号/描述/严重程度/涉及角色
根因分析 每条问题的根本原因追溯和类别归类 5Why分析/类别标签/流程断点
强制流程 按角色划分的6大流程规范 PM/UED/架构/FE/BE/QA各角色流程
角色规则 后续迭代必须严格执行的长效规则 每个角色的具体职责和行为约束
行动项 下次迭代必须完成的改进项 优先级/负责人/截止时间

🛠️ 核心实现

步骤1: 16个问题清单——复盘的起点

功能说明

复盘的第一步是"把所有问题摆在桌面上"。"奇妙科学乐园"项目在首次迭代中暴露了16个问题,涵盖语法错误、环境差异、UI还原度、设计交付、测试覆盖等多个维度。问题的严重程度从"编译报18个错误"到"ViewModel接口文档缺失"不等,但每一个都值得认真分析。

完整代码

// ===== 16个问题清单 =====
// 来源: docs/本次迭代复盘.md

/**
 * 问题编号体系说明:
 * P01-P06: 🔴 严重问题(阻塞开发/影响核心功能)
 * P07-P10: 🟡 中等问题(影响效率/体验)
 * P11-P16: 🟢 轻微问题(可改进/可优化)
 */

// ===== 🔴 严重问题(6个)=====

// P01: 首轮编译报18个ArkTS语法错误
// 现象: spread运算符、padStart、inline type import、saturation、Uint8Array→string等
// 严重程度: 🔴 严重
// 涉及角色: 架构师、FE
// 根因类别: 技术预研缺失

// 项目中真实的语法错误案例:
// ❌ ArkTS strict mode不支持spread运算符
// const newItems = [...oldItems, newItem];

// ❌ ArkTS strict mode不支持inline type import
// import('../model/Experiment').ExperimentStep[]

// ❌ ArkTS strict mode不支持padStart(需使用paddingStart)
// '5'.padStart(2, '0')

// P02: RollupError "Unexpected token"
// 现象: ScienceData.ets中inline type import导致构建报错
// 严重程度: 🔴 严重
// 涉及角色: FE
// 根因类别: 语法兼容性

// P03: Resource→string类型转换编译错误
// 现象: RawCategory/RawExperiment中间接口缺失
// 严重程度: 🔴 严重
// 涉及角色: BE、FE
// 根因类别: 数据模型设计

// 项目中的解决方案——中间接口:
interface RawCategory {
    id: string;
    name: string;
    icon: string;
    iconImage: string;        // string类型(JSON中存储的值)
    topicCoverImage: string;  // string类型
    // ...
}

interface Category {
    id: string;
    name: string;
    icon: string;
    iconImage: Resource;      // Resource类型(UI渲染使用的值)
    topicCoverImage: Resource; // Resource类型
    // ...
}

// 转换函数:
function resolveCategoryResources(rawCategories: RawCategory[]): Category[] {
    const result: Category[] = [];
    for (const item of rawCategories) {
        result.push({
            // ...
            iconImage: resolveResource(item.iconImage),      // string → Resource
            topicCoverImage: resolveResource(item.topicCoverImage),
            // ...
        });
    }
    return result;
}

// P04: UI还原度低于设计稿
// 严重程度: 🔴 严重
// 涉及角色: UED、FE
// 根因类别: 协作流程缺失

// P05: UED未同步产出切图资源
// 严重程度: 🔴 严重
// 涉及角色: UED、FE、PM
// 根因类别: 流程规范缺失

// P06: Previewer环境下数据加载完全失败
// 现象: UIAbility.onCreate不被调用,数据未初始化
// 严重程度: 🔴 严重
// 涉及角色: 架构师、FE
// 根因类别: 环境差异评估不足

// 项目中的解决方案——双防御初始化:
// MainTabs.ets中:
aboutToAppear() {
    if (!scienceData.getIsInitialized()) {
        try {
            const ctx = getContext(this);
            scienceData.init(ctx);        // 兜底初始化
            userPrefs.init(ctx);
            quizEngine.init(ctx);
            achievementManager.init(ctx);
        } catch (err) {
            Logger.error('MainTabs', 'Previewer环境数据初始化失败', err as Error);
        }
    }
}

// ===== 🟡 中等问题(4个)=====

// P07: Context类型编译错误
// 现象: UIAbilityContext与Context类型不兼容
// 根因: ViewModel单例类的context声明为UIAbilityContext窄类型

// ❌ 错误: init参数类型过窄
init(context: common.UIAbilityContext): void { }

// ✅ 正确: 使用联合类型
init(context: common.UIAbilityContext | common.Context): void { }

// P08: Logger.warn()传3个参数,实际只接收2// 现象: error参数被静默丢弃
// 根因: FE调用时未查阅API定义

// ❌ 错误: Logger.warn(TAG, '加载失败', error);
// ✅ 正确: Logger.error(TAG, '加载失败', error);

// P09: 需求范围未在PRD首轮明确收窄到P0核心3// 根因: PRD输出范围过大,未按优先级分批次

// P10: 设计稿未覆盖加载态/错误态/空数据态
// 根因: UED交付物仅包含正常态设计

// 项目中的三态兜底视图实现:
build() {
    if (this.isLoading) {
        // 加载中: 骨架屏
        this.SkeletonContent();
    } else if (this.hasError) {
        // 加载失败: 错误提示+重试按钮
        this.ErrorContent();
    } else {
        // 正常内容
        this.NormalContent();
    }
}

// ===== 🟢 轻微问题(6个)=====

// P11: 资源格式不统一(jpg有白色背景 vs svg透明底)
// P12: Mock数据与rawfile JSON结构无强制同步机制
// P13: 测试未将设计稿还原度比对纳入提测准入条件
// P14: 测试环境覆盖不足(仅Previewer)
// P15: 回归验证流程缺失
// P16: ViewModel接口类型文档缺失

代码解析

1. 问题清单的编排原则

问题编号规则:
  P + 序号(两位数)
  P01 = 最严重/最优先
  P16 = 最轻微

严重程度判定标准:
  🔴 严重: 阻塞开发进程或影响核心功能
      - 编译无法通过(P01、P02、P03)
      - 核心功能不可用(P04、P05、P06)
  🟡 中等: 影响开发效率或用户体验
      - 类型错误需排查(P07)
      - 日志信息丢失(P08)
      - 范围未收窄(P09)
      - 设计不完整(P10)
  🟢 轻微: 可改进但不阻塞
      - 格式不统一(P11)
      - 同步机制缺失(P12)
      - 测试覆盖不足(P13、P14)
      - 流程缺失(P15)
      - 文档缺失(P16)

步骤2: 根本原因分析——"5个为什么"深挖法

功能说明

找到问题是第一步,找到根本原因才是关键。"奇妙科学乐园"的复盘使用了经典的"5个为什么"方法,对每个问题层层追问,直到找到系统性根因。以下是几个典型问题的根因分析过程。

完整代码

// ===== 根因分析案例 =====

/**
 * 案例一: P01 首轮编译报18个ArkTS语法错误
 *
 * Q1: 为什么编译报18个语法错误?
 * A1: 因为代码使用了spread运算符、padStart等ArkTS不支持的语法
 *
 * Q2: 为什么代码使用了这些不支持的语法?
 * A2: 因为FE按TypeScript通用写法编码,没有查阅ArkTS语法限制
 *
 * Q3: 为什么FE没有查阅ArkTS语法限制?
 * A3: 因为开发前没有进行技术预研
 *
 * Q4: 为什么没有进行技术预研?
 * A4: 因为架构师没有在迭代启动前要求输出技术预研报告
 *
 * Q5: 为什么架构师没有要求?
 * A5: 因为项目缺少"技术预研前置"的强制流程
 *
 * ===== 根本原因: 技术预研缺失 + 缺少强制前置流程 =====
 * ===== 类别: 技术预研缺失 =====
 * ===== 应对: 每次迭代启动前,架构师必须输出技术预研报告 =====
 */

/**
 * 案例二: P06 Previewer环境下数据加载完全失败
 *
 * Q1: 为什么Previewer中数据加载失败?
 * A1: 因为EntryAbility.onCreate不被调用
 *
 * Q2: 为什么onCreate不被调用?
 * A2: 因为Previewer使用FakeUIAbility替代了EntryAbility
 *
 * Q3: 为什么不知道FakeUIAbility的存在?
 * A3: 因为架构设计阶段没有评估Previewer环境差异
 *
 * Q4: 为什么没有评估环境差异?
 * A4: 因为架构文档模板中没有"环境差异风险清单"章节
 *
 * Q5: 为什么架构文档模板缺少此章节?
 * A5: 因为这是团队首次开发HarmonyOS项目,经验不足
 *
 * ===== 根本原因: 环境差异评估不足 + 首次HarmonyOS开发经验缺失 =====
 * ===== 类别: 技术预研缺失 =====
 * ===== 应对: 架构文档必须包含"环境差异风险清单"章节 =====
 */

/**
 * 案例三: P04 UI还原度低于设计稿
 *
 * Q1: 为什么UI还原度低于设计稿?
 * A1: 因为FE开发时没有逐项对照设计稿
 *
 * Q2: 为什么FE没有对照设计稿?
 * A2: 因为缺少设计走查流程——FE完成后UED没有进行阶段性验收
 *
 * Q3: 为什么缺少设计走查流程?
 * A3: 因为PRD和开发流程中没有定义"视觉走查"环节
 *
 * Q4: 为什么流程中没有定义?
 * A4: 因为这是团队首次协作,流程规范尚不完善
 *
 * Q5: 为什么流程规范不完善?
 * A5: 因为缺少"需求→设计→开发→测试"链式交付的强制流程
 *
 * ===== 根本原因: 协作流程缺失 =====
 * ===== 类别: 协作流程缺失 =====
 * ===== 应对: FE完成每个页面后,UED必须进行视觉走查 =====
 */

/**
 * 案例四: P08 Logger.warn()传3个参数
 *
 * Q1: 为什么Logger.warn()传3个参数?
 * A1: 因为FE假设warn方法有error参数
 *
 * Q2: 为什么会有这个假设?
 * A2: 因为调用前没有查阅Logger的定义文件
 *
 * Q3: 为什么没有查阅定义?
 * A3: 因为缺少"调用前必须查阅API定义"的编码规范
 *
 * ===== 根本原因: 编码习惯 =====
 * ===== 类别: 编码规范问题 =====
 * ===== 应对: 调用任何工具类/公共方法前必须先阅读其定义 =====
 */

代码解析

1. 根因类别分布与对策

根因类别 问题编号 对策方向
技术预研缺失 P01、P02、P06、P07 强制技术预研前置
协作流程缺失 P04、P05、P09 建立链式交付流程
编码规范问题 P03、P08、P11 制定编码规范+代码审查
设计规范不完整 P04、P05、P10 完善设计交付物标准
测试流程缺失 P13、P14、P15 完善测试准入和回归流程
文档规范缺失 P16 补充JSDoc/TSDoc注释

原理/说明:

  • "5个为什么"的目的是找到"系统性根因",而非"个人失误"
  • 系统性根因通常指向流程缺失、规范不完善或工具不足
  • 个人失误(如P08不看API定义)的根因是"缺少规范",而不是"个人能力差"
  • 正确的根因分析应该产出"制度性改进措施",而非"批评个人"

步骤3: 强制流程规范——按角色制定的6大流程

功能说明

根因分析完成后,最关键的一步是制定"防止再犯"的强制流程。"奇妙科学乐园"的复盘产出物中,最核心的价值不是16个问题清单,而是由此诞生的6大强制流程规范。这些流程按角色划分,每个角色都有明确的"必须做"和"禁止做"清单。

完整代码

// ===== 强制流程规范 =====
// 来源: docs/本次迭代复盘.md

// ===== 3.1 需求管理流程(PM负责)=====

/**
 * PM强制流程(3条):
 *
 * F-PM-1: PRD必须明确迭代范围
 *   - 每版PRD必须包含"本次迭代范围"章节
 *   - 使用P0/P1/P2优先级标注功能
 *   - 明确纳入/排除的功能清单
 *
 * F-PM-2: 需求变更必须走变更通知
 *   - 任何需求变更必须更新PRD版本号
 *   - 通过@提醒机制通知下游所有角色
 *   - 变更影响评估(工期/资源/风险)
 *
 * F-PM-3: PRD交付物标准
 *   - 功能描述
 *   - 交互流程
 *   - UI状态覆盖(正常/加载/错误/空数据)
 *   - 验收标准
 */

// ===== 3.2 UED设计交付流程(UED负责)=====

/**
 * UED强制流程(4条):
 *
 * F-UED-1: 设计交付物四件套
 *   (1)高保真设计稿
 *   (2)交互说明文档
 *   (3)切图资源包(统一SVG透明底)
 *   (4)标注文档(间距/字号/色值/圆角)
 *
 * F-UED-2: UI状态全覆盖
 *   设计稿必须覆盖:
 *   - 正常态
 *   - 加载态(骨架屏)
 *   - 错误态
 *   - 空数据态
 *   - 网络异常态
 *
 * F-UED-3: 阶段性视觉走查
 *   FE完成每个页面后,UED必须在1个工作日内完成视觉走查
 *   走查通过后才可进入测试环节
 *
 * F-UED-4: 切图资源规范
 *   图标统一SVG格式(透明底)
 *   主色 #ff6b6b
 *   线条2px
 *   48x48 viewBox
 *   放到 resources/base/media/ 目录
 */

// ===== 3.3 架构设计流程(架构师负责)=====

/**
 * 架构师强制流程(4条):
 *
 * F-ARCH-1: 技术预研强制前置
 *   每次迭代启动前必须输出技术预研报告,包含:
 *   - 目标平台语法限制(ArkTS strict mode不支持spread/padStart等)
 *   - 已知兼容性问题(Previewer FakeUIAbility、Context类型差异)
 *   - 环境差异风险清单
 *
 * F-ARCH-2: 任务拆分必须里程碑化
 *   M1/P0核心3页(首页/科普/我的)→ 交付: 核心页面可交互
 *   M2/P1功能增强(答题/成就/实验)→ 交付: 辅助功能可用
 *   M3/P2完善优化(动画/交互/性能)→ 交付: 上线就绪
 *   每个里程碑有明确的交付物和验收标准
 *
 * F-ARCH-3: 环境差异风险清单
 *   架构文档必须包含:
 *   | 环境 | onCreate | rawfile | Preferences | context类型 |
 *   |------|---------|---------|-------------|-----------|
 *   | 真机 | 正常调用 | 可用 | 可用 | UIAbilityContext |
 *   | Previewer | 不调用 | 不可用 | 不可用 | UIContext |
 *
 * F-ARCH-4: 类型设计原则
 *   跨环境调用的接口参数使用基类:
 *   ✅ init(context: common.UIAbilityContext | common.Context)
 *   ❌ init(context: common.UIAbilityContext)
 */

// ===== 3.4 前端开发规范(FE负责)=====

/**
 * FE强制流程(5条):
 *
 * F-FE-1: 禁止emoji占位
 *   任何图标/图片必须使用 $r('app.media.xxx') 引用真实资源
 *   禁止使用emoji或Unicode字符作为UI元素
 *
 * F-FE-2: 开发前必须查阅API定义
 *   调用任何工具类/公共方法前,必须先阅读其定义文件
 *   确认参数数量和类型,禁止凭主观假设传参
 *
 * F-FE-3: 开发前必须技术预研
 *   针对ArkTS strict mode的语法限制,开发前查阅官方文档
 *   或进行小规模验证(创建test page验证语法)
 *
 * F-FE-4: 页面还原必须逐项对照
 *   FE开发每个页面时,必须逐项对照设计稿:
 *   间距、字号、色值、圆角、阴影、图标位置
 *   偏差超过2px需调整
 *
 * F-FE-5: 修改前必须读取完整文件
 *   修改任何文件前,必须先完整读取当前文件内容
 *   梳理原有逻辑后再修改
 */

// ===== 3.5 后端开发规范(BE负责)=====

/**
 * BE强制流程(2条):
 *
 * F-BE-1: 数据模型必须声明完整接口
 *   所有数据模型(含中间转换模型)必须显式声明interface
 *   禁止使用未类型化的对象字面量
 *
 * 示例: P03的解决方案
 * 原问题: JSON反序列化时Resource类型与string直接混用
 * 解决方案: 声明RawCategory中间接口
interface RawCategory {
    iconImage: string;        // JSON中的string值
    topicCoverImage: string;
}
interface Category {
    iconImage: Resource;      // UI渲染需要的Resource值
    topicCoverImage: Resource;
}
 *
 * F-BE-2: Mock数据必须与JSON schema保持同步
 *   Mock数据函数顶部必须添加注释:
 *   // 对应JSON文件: categories.json
 *   // 最后同步日期: 2026-07-13
 *   // JSON结构变更时必须同步更新Mock
 */

// ===== 3.6 测试验收流程(QA负责)=====

/**
 * QA强制流程(4条):
 *
 * F-QA-1: 提测准入检查表
 *   提测前必须通过:
 *   (1) 编译零错误
 *   (2) 设计稿视觉还原度走查通过
 *   (3) 核心功能冒烟自测通过
 *
 * F-QA-2: 多环境覆盖
 *   测试必须覆盖:
 *   - DevEco Previewer
 *   - 模拟器/真机(如可用)
 *   不可仅依赖单一环境
 *
 * F-QA-3: Bug修复后强制回归
 *   每轮Bug修复后,QA必须执行回归测试:
 *   - 覆盖修复模块
 *   - 覆盖关联模块
 *   不可仅验证修复点
 *
 * F-QA-4: 边界场景测试用例
 *   测试用例必须覆盖:
 *   - 空数据
 *   - 网络异常
 *   - 快速切换
 *   - 资源加载失败
 *   - 大列表滚动
 */

代码解析

1. 强制流程的落地保障

// ===== 如何确保强制流程不被架空?=====

/**
 * 保障措施1: 流程纳入角色规则
 *   - 每个角色的强制流程写入"角色长效规则"文档
 *   - 下次迭代启动前全员确认已阅读并理解
 *
 * 保障措施2: 里程碑门禁
 *   - M1交付前: PM确认PRD迭代范围 + UED确认切图交付
 *   - M2交付前: FE确认编译零错误 + UED确认视觉走查
 *   - M3交付前: QA确认多环境覆盖 + 全员确认回归通过
 *
 * 保障措施3: 行动项跟踪
 *   - P0行动项必须在下次迭代M1前完成
 *   - 架构师负责确认全员已执行
 *   - 未完成的项目阻塞对应里程碑
 */

步骤4: 角色长效规则——让每个角色有章可循

功能说明

复盘的最终产出不是"问题清单"本身,而是每个角色的"长效规则"——一份明确到可执行的行为准则。这些规则从复盘的16个问题中提炼而来,在后续迭代中必须严格执行。

完整代码

// ===== 角色长效规则(后续迭代必须严格执行)=====

// ===== @pm-product 产品经理 =====
export const PmRules = {
    // PRD规范
    prdMustHaveScope: true,           // 每版PRD必须包含"迭代范围"章节
    prdMustHavePriority: true,        // P0/P1/P2优先级明确
    changeMustNotify: true,           // 需求变更必须更新版本号 + @通知全员
    prdMustHaveAcceptance: true,      // PRD中必须定义"验收标准"
    kickoffBeforeDev: true,           // 需求交底会议必须在开发启动前完成
};

// ===== @ued-design 设计师 =====
export const UedRules = {
    deliverFourPieces: true,          // 设计交付物四件套(设计稿+交互+切图+标注)
    cutFormatSvg: true,               // 切图统一SVG格式、透明底、48x48 viewBox
    visualReviewWithin1Day: true,    // FE完成后1个工作日内完成视觉走查
    coverAllStates: true,            // 设计稿覆盖全部UI状态(正常/加载/错误/空数据)
    trackReviewIssues: true,         // 视觉走查问题记录在"设计走查问题单"中
};

// ===== @arch-lead 架构师 =====
export const ArchRules = {
    techPreviewReport: true,         // 每次迭代启动前输出"技术预研报告"
    milestoneBreakdown: true,        // 任务拆分里程碑化(M1/M2/M3)
    envDiffRiskList: true,           // 架构文档包含"环境差异风险清单"
    wideTypeForContext: true,        // 跨环境接口参数使用宽类型(基类)
    fullApiDocs: true,               // ViewModel公共接口有完整JSDoc注释
};

// ===== @fe-dev 前端开发 =====
export const FeRules = {
    noEmojiInUI: true,               // 禁止emoji/Unicode字符作为UI图标
    checkApiBeforeCall: true,         // 调用公共方法前必须查阅API定义
    pixelPerfectDev: true,            // 页面开发逐项对照设计稿,偏差>2px调整
    readFileBeforeEdit: true,         // 修改文件前必须先读取完整内容
    compileBeforeDeliver: true,       // 每次交付前编译零错误
};

// ===== @be-dev 后端开发 =====
export const BeRules = {
    explicitInterfaces: true,         // 所有数据模型显式声明interface
    rawToModelPipeline: true,         // JSON→Model转换有中间接口(RawXxx → Xxx)
    mockSyncAnnotation: true,         // Mock数据注释说明对应JSON文件和同步日期
};

// ===== @qa-test 测试工程师 =====
export const QaRules = {
    admissionChecklist: true,         // 提测准入: 编译零错误+视觉走查+冒烟通过
    multiEnvCoverage: true,           // 测试覆盖Previewer+模拟器/真机
    regressionAfterFix: true,        // Bug修复后执行回归测试
    edgeCaseCoverage: true,           // 测试用例覆盖边界场景
};

代码解析

1. 角色规则的可执行性检查

规则可执行性评判标准:
  ① 可量化: 能用"是/否"判断是否执行?(而非"尽量""适当")
  ② 可检查: 第三方能否验证?(而非仅靠自觉)
  ③ 有截止: 有明确的时间节点?(而非"尽快")

✅ 好的规则: "FE完成每个页面后,UED必须在1个工作日内完成视觉走查"
   → 可量化(有/无走查)、可检查(走查记录)、有截止(1个工作日)

❌ 差的规则: "FE开发时注意UI还原度"
   → 不可量化(什么叫"注意"?)、不可检查(没有走查记录)、无截止

步骤5: 行动项跟踪——从复盘到落地

功能说明

复盘的最终目标是"行动"——把讨论变成具体的改进项,指定负责人和截止时间。"奇妙科学乐园"的复盘产出了6个行动项,按优先级分为P0/P1/P2三个层级。

完整代码

// ===== 行动项跟踪表 =====

/**
 * | 优先级 | 行动项 | 负责人 | 截止时间 |
 * |--------|--------|--------|---------|
 * | 🔴 P0 | 旧版jpg图标全部替换为SVG格式(icon_back/icon_search/icon_speak等8个) | UED+FE | 下次迭代M1 |
 * | 🔴 P0 | 非P0页面emoji替换(Profile/Settings/History/LabDetail等7个页面) | UED切图+FE挂接 | 下次迭代M2 |
 * | 🟡 P1 | ViewModel公共接口补充JSDoc/TSDoc完整注释 | 架构+BE | 下次迭代M1 |
 * | 🟡 P1 | Mock数据添加JSON schema校验注释和同步日期标注 | BE | 下次迭代M1 |
 * | 🟡 P1 | 编写边界场景测试用例(空数据/资源失败/快速切换等) | QA | 下次迭代M2 |
 * | 🟢 P2 | 输出"技术预研报告"模板,固化到项目docs/目录 | 架构 | 下次迭代启动前 |
 */

// 行动项跟踪要点:
// 1. P0项必须在下次迭代M1/M2前完成,阻塞里程碑交付
// 2. P1项应该在下次迭代内完成,不阻塞但优先处理
// 3. P2项尽快完成,可以跨迭代
// 4. 架构师负责确认所有P0项在下次迭代启动前已完成

⚠️ 常见问题与解决方案

问题1: 复盘会变成"追责大会"

现象:
复盘讨论中逐渐演变为互相指责,"这个问题是因为你没做好""不对,是因为你给的文档不完整"。

原因:
复盘会议没有提前设定"对事不对人"的原则,参与者将"问题"等同于"个人过失"。

解决方案:

1. 会议开始前宣读复盘原则:
   "我们复盘的是流程和系统,不是个人能力"
   "每个问题都追问5个为什么,直到找到制度性根因"
2. 主持人严格控场:
   发现讨论转向个人指责时,立即引导回根因分析
   "这个问题的根因是流程缺失,不是某个人能力不足"
3. 问题描述使用中性语言:
   "数据模型设计中未考虑JSON反序列化链路"
   而非"BE没有设计好数据模型"

问题2: 复盘产出物被束之高阁

现象:
复盘会议产出了16个问题和6大流程规范,但后续迭代中仍然重复犯同样的错误。

原因:
复盘产出物没有被转化为日常工作中的"强制检查点",没有纳入里程碑门禁。

解决方案:

1. 流程纳入里程碑门禁:
    M1交付前必须: PRD迭代范围确认 + 切图交付确认
    M2交付前必须: 编译零错误 + 视觉走查通过
2. 行动项指派到个人:
    每条行动项有明确的负责人和截止时间
3. 下次迭代启动前全员确认:
    架构师负责确认全员已阅读并理解复盘结论
4. 将核心流程固化为工具:
    如PR模板中嵌入自审检查表

📝 本章小结

核心知识点

本文系统讲解了"奇妙科学乐园"项目全员复盘会的完整方法论,主要包括:

1. 复盘方法论框架

  • 四步法: 问题清单 → 根因分析 → 强制流程 → 行动项跟踪
  • "5个为什么"深挖根因,找到系统性改进方向
  • 按严重程度分级(严重/中等/轻微),按优先级处理

2. 16个问题清单与根因分析

  • 6个严重问题: ArkTS语法错误、环境差异、UI还原度
  • 4个中等问题: 类型兼容、日志参数、需求范围、设计不完整
  • 6个轻微问题: 资源格式、Mock同步、测试覆盖、回归流程、文档缺失
  • 根因归结为6大类别: 技术预研缺失、协作流程缺失、编码规范问题、设计规范不完整、测试流程缺失、文档规范缺失

3. 6大强制流程规范

  • PM: PRD迭代范围 + 变更通知 + 交付物标准
  • UED: 设计四件套 + UI状态全覆盖 + 视觉走查 + 切图规范
  • 架构师: 技术预研 + 里程碑化 + 环境风险清单 + 宽类型设计
  • FE: 禁止emoji + 查阅API + 逐项对照 + 读取再改 + 编译通过
  • BE: 显式接口 + Mock同步 + 中间接口
  • QA: 提测准入 + 多环境覆盖 + 强制回归 + 边界用例

4. 角色长效规则与行动项跟踪

  • 6个角色各有明确的"必须做"和"禁止做"清单
  • 规则可量化、可检查、有截止时间
  • P0行动项阻塞里程碑交付

最佳实践总结

复盘不是追责,是找系统性改进

追问"为什么"直到找到制度根因,而非停在"某个人犯了错"
制度性问题需要制度性解决方案,个人问题需要培训和支持

流程必须有强制检查点

没有门禁的流程等于没有流程
每个关键节点设置检查清单,通过才能进入下一阶段

行动项必须可跟踪

每条行动项: 负责人 + 截止时间 + 验收标准
P0项阻塞里程碑,确保最高优先级的改进不会被跳过

下一步预告

在后续文章中,我们将:

  • 🚀 展望"奇妙科学乐园"后续迭代的规划方向
  • 📊 分析复盘认定的问题在后续迭代中的改进效果
  • 🏆 总结100篇技术解读系列的核心知识点图谱

🔗 相关链接


💡 提示: 建议结合项目源码中的 docs/本次迭代复盘.md 对照阅读,理解16个问题在真实项目中的具体表现。将本文的"5个为什么"分析方法和强制流程模板应用到自己的项目中,将每次失败的教训转化为团队的系统性改进。

Logo

讨论HarmonyOS开发技术,专注于API与组件、DevEco Studio、测试、元服务和应用上架分发等。

更多推荐