AI宝宝辅食搭配:HarmonyOS 原生应用开发全流程实践

前言

在当今移动互联网时代,AI 技术正在深刻改变着每一个行业。育儿领域也不例外——新生代父母对于科学喂养、精准营养的需求日益增长。本文以 HarmonyOS 平台上的一款 AI 应用"AI宝宝辅食搭配"为例,详细阐述从需求对齐到最终交付评估的完整开发流程。该应用旨在帮助家长根据宝宝的月龄、过敏源和口味偏好,智能生成个性化的辅食搭配方案,涵盖食谱推荐、营养成分分析、禁忌提醒及周计划等丰富功能。

本文将沿用我团队在实践中总结的 6A 开发方法论——对齐(Align)→ 架构(Architect)→ 原子化(Atomize)→ 审批(Approve)→ 自动化执行(Automate)→ 评估(Assess),逐阶段深入剖析整个开发过程。同时,本文会穿插大量 ArkTS 代码示例和真实项目文件路径,供读者参考。


在这里插入图片描述

一、对齐阶段(Align)

对齐阶段的目标是将模糊的原始需求转化为精确、可执行的开发规范。良好的对齐能避免后续开发中的返工和误解,是项目成功的基石。

1.1 项目上下文分析

"AI宝宝辅食搭配"是 HarmonyOS 平台上一个大型 AI 应用矩阵中的子应用。整个项目采用 ArkTS 语言,基于 ArkUI 声明式框架 构建 UI,遵循 MVVM 架构模式。项目结构如下:

MyApplication/
├── oh-package.json5              # 项目级依赖配置
├── build-profile.json5           # 构建配置文件
├── entry/
│   ├── oh-package.json5          # 模块级依赖配置
│   ├── build-profile.json5       # 模块构建配置
│   └── src/main/
│       ├── module.json5          # HarmonyOS 模块配置
│       ├── resources/            # 资源文件
│       │   └── rawfile/apps/
│       │       └── apps.json     # 应用注册配置文件
│       └── ets/
│           ├── pages/
│           │   └── Index.ets     # 主入口页面(应用列表)
│           ├── entryability/
│           │   └── EntryAbility.ets  # Ability 生命周期
│           └── apps/
│               └── AI宝宝辅食搭配/
│                   ├── AI宝宝辅食搭配Page.ets    # 页面层
│                   ├── AI宝宝辅食搭配Model.ets   # 数据模型层
│                   └── AI宝宝辅食搭配Service.ets # 业务逻辑层

通过分析现有的 Index.ets 主入口页面,可以看到整个应用矩阵采用统一的架构模式:

  • 所有子应用通过 apps.json 注册配置信息
  • 主页面动态加载配置并生成网格列表
  • 用户点击卡片后通过路由跳转到对应子应用页面

apps.json 中"AI宝宝辅食搭配"的注册配置如下:

{
  "icon": "👶",
  "title": "AI宝宝辅食搭配",
  "subtitle": "宝宝辅食",
  "color": "#10B981",
  "bg": "#ECFDF5",
  "border": "#A7F3D0",
  "page": "apps/AI宝宝辅食搭配/AI宝宝辅食搭配Page",
  "cat": "健康生活"
}

这一配置确保了该应用在"健康生活"分类下展示,并以绿色系配色呈现。

1.2 需求理解与确认

原始需求:“开发一个 AI 宝宝辅食搭配应用,帮助家长根据宝宝情况生成辅食方案。”

经过与产品经理和业务方的多轮沟通,我们将需求细化为以下核心功能点:

功能模块详细描述优先级
月龄输入用户输入宝宝月龄(如 6、8、12 等)P0
过敏源输入用户输入宝宝已知的过敏食物P0
口味偏好用户输入宝宝的口味偏好P0
AI 生成辅食基于输入信息生成个性化辅食方案P0
结果展示展示食谱、食材、步骤、营养成分等P0
周计划生成生成一周的辅食搭配计划P1
禁忌提醒针对月龄和过敏源给出禁忌食物提醒P1

1.3 技术约束确认

在技术对齐阶段,我们重点确认了以下关键约束:

ArkTS 语言约束:HarmonyOS 的 ArkTS 是 TypeScript 的子集,有许多严格限制。例如不支持 any/unknown 类型、不支持解构赋值、不支持 in 运算符、不支持 Function.bind/apply/call、不支持 as const 断言、不支持索引签名等。这些约束对我们的代码编写方式产生了深远影响。

API 规范:UI 组件使用 @kit.ArkUI 提供的 ArkUI 声明式组件,路由使用 router API。所有 API 调用前需确认对应 API Level 和设备支持情况。

在 ArkUI 中,我们使用的核心组件包括:

  • Column / Row:弹性布局容器,类似于 Flexbox
  • Text:文本显示组件,支持富文本样式
  • TextInput:文本输入组件,支持占位符和事件回调
  • Button:按钮组件,支持自定义样式
  • Scroll:可滚动容器,支持垂直和水平滚动
  • ForEach:列表渲染组件,基于数据源循环生成子组件
  • Blank:空白填充组件,用于弹性布局中的空间分配
  • Flex:弹性布局容器,支持换行和主轴对齐

资源管理:UI 中展示的文本应优先使用 $r 引用资源文件,颜色字符串直接使用十六进制值,常量和枚举值统一管理。

ArkUI 动画规范:在后续迭代中,需要遵循以下动画最佳实践:

  • 优先使用 HarmonyOS 原生动画 API,通过 @State 驱动动画
  • 对于包含复杂子组件的动画,设置 renderGroup(true) 减少渲染批次
  • 避免在动画过程中频繁改变组件的 width、height、padding、margin 等布局属性,这会影响性能

1.4 输入数据规范化

在需求对齐过程中,我们特别关注了输入数据的规范化问题。用户输入的月龄、过敏源和偏好信息,最终通过 Record<string, Object> 类型传递给服务层。这种设计基于以下考量:

  1. 灵活性:Record<string, Object> 可以容纳任意数量和类型的输入字段,便于后续扩展
  2. 类型安全:虽然 Object 类型较为宽泛,但 ArkTS 不支持 any,这是最接近且合规的选择
  3. 与 ArkTS 兼容:ArkTS 允许在 Record<K, V> 类型上使用索引访问,rec[index] 的类型为 V | undefined

输入数据的生命周期如下:

  1. 用户在 TextInput 中输入文本
  2. onChange 回调触发,将值写入 this.inputData['月龄'](或其他字段名)
  3. 用户点击"生成辅食"按钮
  4. inputData 被传递给 service.generateData(this.inputData)
  5. Service 层从 inputData 中读取各字段值,生成结果

1.5 对齐文档输出

对齐阶段完成后,我们输出了 ALIGNMENT_AI宝宝辅食搭配.md 文档,包含完整的项目上下文分析、需求细化表、技术约束清单以及所有已澄清的疑问。该文档为后续架构设计提供了坚实的基础,确保了所有团队成员对项目目标和技术方案的理解一致。


二、架构阶段(Architect)

架构阶段的目标是基于对齐阶段的共识,设计出清晰的系统架构、模块划分和接口契约。

2.1 整体架构设计

"AI宝宝辅食搭配"采用经典的三层架构:

┌──────────────────────────────────────────────┐
│                视图层(View)                  │
│   AI宝宝辅食搭配Page.ets                      │
│   - 用户输入采集                              │
│   - 结果展示                                  │
│   - 状态管理                                  │
├──────────────────────────────────────────────┤
│              业务逻辑层(Service)             │
│   AI宝宝辅食搭配Service.ets                   │
│   - 数据生成逻辑                              │
│   - AI 推理调度(Mock 阶段)                   │
│   - 数据校验                                  │
├──────────────────────────────────────────────┤
│              数据模型层(Model)               │
│   AI宝宝辅食搭配Model.ets                     │
│   - 数据实体定义                              │
│   - 数据类型约束                              │
└──────────────────────────────────────────────┘

2.2 分层详解

数据模型层(Model)

数据模型层是整个应用的根基。在 ArkTS 中,由于不支持 any 和 unknown 类型,所有数据必须有明确的类型定义。我们创建了 AI宝宝辅食搭配Data 类来承载所有辅食数据:

// 文件路径: entry/src/main/ets/apps/AI宝宝辅食搭配/AI宝宝辅食搭配Model.ets
export class AI宝宝辅食搭配Data {
  recipes: string[] = []          // 食谱列表
  name: string = ''               // 食谱名称
  ingredients: string[] = []      // 食材列表
  steps: string[] = []            // 制作步骤
  step: string = ''               // 当前步骤
  action: string = ''             // 操作动作
  tip: string = ''                // 小贴士
  calories: string = ''           // 卡路里
  iron: string = ''               // 铁含量
  calcium: string = ''            // 钙含量
  protein: string = ''            // 蛋白质含量
  texture: string = ''            // 口感
  allergen_check: string = ''     // 过敏源检查
  weekly_plan: string = ''        // 周计划
  nutritional_focus: string = ''  // 营养重点
  tips: string = ''               // 综合建议
  forbidden: string[] = []        // 禁忌食物列表

  constructor() {
    // 所有字段在构造函数中显式初始化
    this.recipes = []
    this.name = ''
    this.ingredients = []
    this.steps = []
    this.step = ''
    this.action = ''
    this.tip = ''
    this.calories = ''
    this.iron = ''
    this.calcium = ''
    this.protein = ''
    this.texture = ''
    this.allergen_check = ''
    this.weekly_plan = ''
    this.nutritional_focus = ''
    this.tips = ''
    this.forbidden = []
  }
}

设计要点:

  • 遵循 ArkTS 规范,所有字段在类声明中直接定义,而非在构造函数中声明
  • 每个字段都有明确的类型标注,避免使用 any
  • 字符串数组字段(recipes、ingredients、steps、forbidden)初始化为空数组
  • 构造函数中再次显式初始化所有字段,确保可读性和确定性
  • 字段类型全部为 string 或 string[],保持数据类型的一致性,简化序列化和反序列化过程

为什么选择全字符串类型?

在数据模型设计中,我们刻意将所有字段设计为字符串类型,而不是使用数字类型(如 calories 用 number 表示)。这主要基于以下考虑:

  1. UI 展示直接:所有数据最终都通过 Text 组件展示,字符串类型无需额外转换
  2. AI 输出兼容:无论是 Mock 数据还是真实 AI 服务,输出格式通常为文本,字符串类型最为通用
  3. 类型统一:避免类型转换的复杂性,降低代码出错概率
  4. 扩展性:字符串可以包含格式化信息(如"约 120 千卡"),比纯数字更灵活
业务逻辑层(Service)

业务逻辑层负责处理数据生成逻辑。在 MVP 阶段,我们使用 Mock 数据来模拟 AI 推理结果:

// 文件路径: entry/src/main/ets/apps/AI宝宝辅食搭配/AI宝宝辅食搭配Service.ets
import { AI宝宝辅食搭配Data } from './AI宝宝辅食搭配Model'

export class AI宝宝辅食搭配Service {
  private model: AI宝宝辅食搭配Data

  constructor() {
    this.model = new AI宝宝辅食搭配Data()
  }

  // 生成AI宝宝辅食搭配数据
  generateData(input: Record<string, Object>): AI宝宝辅食搭配Data {
    let result: AI宝宝辅食搭配Data = new AI宝宝辅食搭配Data()
    // Mock data generation based on input
    let age_monthsVal: string = String(input['age_months'] || '')

    result.recipes = ['示例数据1', '示例数据2', '示例数据3']
    result.weekly_plan = '生成结果:' + age_monthsVal
    result.nutritional_focus = '生成结果:' + age_monthsVal
    result.tips = '生成结果:' + age_monthsVal
    result.forbidden = ['示例项1', '示例项2', '示例项3']
    return result
  }
}

设计要点:

  • generateData 方法接收 Record<string, Object> 类型的输入参数,这是 ArkTS 中处理动态键值对的推荐方式
  • 返回类型明确标注为 AI宝宝辅食搭配Data,符合 ArkTS 不支持仅基于返回类型推断泛型的要求
  • 业务逻辑与 UI 完全解耦,便于后续替换为真实的 AI API 调用
视图层(Page)

视图层使用 ArkUI 的声明式语法构建 UI。我们采用 @Component 装饰器定义组件,使用 @State 装饰状态变量驱动 UI 更新:

// 文件路径: entry/src/main/ets/apps/AI宝宝辅食搭配/AI宝宝辅食搭配Page.ets
import { AI宝宝辅食搭配Data } from './AI宝宝辅食搭配Model'
import { AI宝宝辅食搭配Service } from './AI宝宝辅食搭配Service'
import { router } from '@kit.ArkUI'

@Entry
@Component
struct AI宝宝辅食搭配Page {
  @State inputData: Record<string, Object> = {}
  @State resultData: AI宝宝辅食搭配Data | null = null
  @State showResult: boolean = false
  private service: AI宝宝辅食搭配Service = new AI宝宝辅食搭配Service()

  build() {
    Column() {
      // 可爱Header
      Row() {
        Text('← 返回')
          .fontSize(13)
          .fontColor('#F472B6')
          .onClick(() => { router.back() })
        Blank()
        Column() {
          Text('📱 AI宝宝辅食搭配')
            .fontSize(17)
            .fontWeight(FontWeight.Bold)
            .fontColor('#831843')
          Text('☆ 成长手册 ☆')
            .fontSize(10)
            .fontColor('#F472B6')
            .margin({ top: 2 })
        }
        Blank()
        Text('👶').fontSize(24)
      }
      // ... 后续 UI 构建
    }
    .width('100%').height('100%')
    .backgroundColor('#FCE7F3')
  }
}

2.3 数据流设计

应用的数据流遵循 单向数据流 原则:

用户输入 → @State inputData 更新 → 调用 Service.generateData()
  → Service 处理逻辑 → 返回 AI宝宝辅食搭配Data
  → @State resultData 更新 → UI 自动刷新

关键的数据流路径:

  1. 输入阶段:用户在 TextInput 组件中输入月龄、过敏源和偏好信息,onChange 回调实时更新 inputData 对象
  2. 触发阶段:用户点击"生成辅食"按钮,调用 service.generateData(this.inputData) 方法
  3. 渲染阶段:返回结果赋值给 resultData,设置 showResult = true,触发条件渲染,展示完整的辅食方案

2.4 模块依赖关系

AI宝宝辅食搭配Page.ets
  ├── import AI宝宝辅食搭配Data  (from Model)
  ├── import AI宝宝辅食搭配Service (from Service)
  └── import router              (from @kit.ArkUI)

AI宝宝辅食搭配Service.ets
  └── import AI宝宝辅食搭配Data  (from Model)

AI宝宝辅食搭配Model.ets      (无依赖,纯数据定义)

2.5 接口契约设计

接口输入输出说明
generateData(input)Record<string, Object>AI宝宝辅食搭配Data根据用户输入生成辅食方案
页面路由无(通过 router.pushUrl)跳转至目标页面从 Index 页面跳转到本应用

2.6 组件树设计

整个页面的组件树结构如下,展示了 ArkUI 声明式组件的嵌套关系:

Column (根容器, 粉色背景 #FCE7F3)
├── Row (Header 区域)
│   ├── Text ("← 返回")
│   ├── Blank (弹性空白)
│   ├── Column (标题区域)
│   │   ├── Text ("📱 AI宝宝辅食搭配")
│   │   └── Text ("☆ 成长手册 ☆")
│   ├── Blank (弹性空白)
│   └── Text ("👶")
├── Scroll (可滚动内容区)
│   └── Column (内容容器)
│       ├── Row (Emoji 装饰行)
│       │   └── ForEach (🌸 ⭐ 🦋 🌈 🍼)
│       ├── Column (输入区域卡片)
│       │   ├── Text ("🍼 月龄")
│       │   ├── TextInput (月龄输入)
│       │   ├── Text ("🍼 过敏源")
│       │   ├── TextInput (过敏源输入)
│       │   ├── Text ("🍼 偏好")
│       │   └── TextInput (偏好输入)
│       ├── Button ("📱 生成辅食")
│       └── Column (结果区域卡片, 条件渲染)
│           ├── Text ("🍽 今日辅食")
│           ├── Text ("Recipes")
│           │   └── ForEach (食谱列表)
│           ├── Row (name)
│           ├── Text ("Ingredients")
│           │   └── ForEach (食材列表)
│           ├── Text ("Steps")
│           │   └── ForEach (步骤列表)
│           ├── Row (step)
│           ├── Row (action)
│           ├── Row (tip)
│           ├── Row (calories)
│           ├── Row (iron)
│           ├── Row (calcium)
│           ├── Row (protein)
│           ├── Row (texture)
│           ├── Row (allergen_check)
│           ├── Row (weekly_plan)
│           ├── Row (nutritional_focus)
│           ├── Row (tips)
│           └── Text ("Forbidden")
│               └── ForEach (禁忌列表)

2.7 设计系统与样式规范

在架构阶段,我们还定义了统一的样式规范,确保 UI 的一致性和可维护性。

配色方案:

"AI宝宝辅食搭配"采用粉色系配色方案,营造温馨、可爱的视觉风格,贴合母婴类应用的用户心理预期:

用途颜色值应用场景
页面背景色#FCE7F3整个页面的背景
主色调#EC4899按钮背景色
深色强调#831843标题文字颜色
浅色强调#F472B6辅助文字、返回按钮
边框色#F9A8D4输入框、卡片边框
白色#FFFFFF卡片背景、输入框背景
深色文字#333333内容文字颜色
灰色文字#666666标签文字颜色

间距规范:

ArkUI 中通过 margin 和 padding 属性控制间距,我们采用以下规范:

  • 页面边距:padding({ left: 18, right: 18 }),保持内容与屏幕边缘的适当距离
  • 卡片内边距:padding(18),输入区域和结果区域使用统一的内边距
  • 组件间距:margin({ top: 6, bottom: 3 }),标签与输入框之间的间距
  • 按钮间距:margin({ top: 18, bottom: 14 }),按钮与上下元素的间距
  • 列表项间距:padding({ top: 2, bottom: 2 }),列表项之间的紧凑间距

圆角规范:

  • 输入框:borderRadius(8),小圆角,柔和而不失现代感
  • 卡片:borderRadius(16),大圆角,营造卡片式设计
  • 按钮:borderRadius(25),全圆角,胶囊按钮风格

字体规范:

  • 标题文字:fontSize(17) + fontWeight(FontWeight.Bold),醒目突出
  • 标签文字:fontSize(11),小巧精致
  • 内容文字:fontSize(12),清晰易读
  • 输入文字:fontSize(13),略大于内容文字
  • 按钮文字:fontSize(16) + fontWeight(FontWeight.Bold),引导用户点击

这套设计系统确保了整个页面在视觉上的一致性,无论是输入区域、按钮还是结果展示区域,都遵循统一的视觉语言。

2.8 异常处理策略

在 ArkTS 中,catch 子句变量不能标注类型(不支持 any/unknown),因此我们采用以下模式:

try {
  let result = this.service.generateData(this.inputData)
  this.resultData = result
  this.showResult = true
} catch {
  // 省略类型标注,ArkTS 不允许在 catch 中标注类型
  console.error('生成辅食数据失败')
}

此外,对于可能为空的 resultData 对象,我们在访问其属性前进行了严格的空值检查。由于 resultData 的类型是 AI宝宝辅食搭配Data | null(联合类型),在访问其属性时必须先确认非空,否则编译器会报错。这种编译时检查机制有效地避免了空指针异常。

对于数组字段(如 recipes、ingredients、steps、forbidden),我们在使用 ForEach 渲染前也进行了存在性检查:

if (this.resultData.recipes) {
  ForEach(this.resultData.recipes, ...)
}

这种防御性编程模式在 ArkTS 中不仅是好的实践,更是编译器的强制要求。


三、原子化阶段(Atomize)

原子化阶段将整个开发任务分解为可独立执行、可验证的小任务。这种分解方式有助于并行开发、精确追踪进度和降低风险。

3.1 任务分解

我们将"AI宝宝辅食搭配"的开发任务分解为以下原子级任务:

任务 A:数据模型定义(A1 - A5)
任务 ID任务描述预估工时依赖
A1定义 AI宝宝辅食搭配Data 类,包含所有字段0.5h无
A2为每个字段设置默认值和类型标注0.5hA1
A3编写构造函数,确保所有字段初始化0.25hA2
A4导出类供其他模块使用0.25hA3
A5单元测试:验证数据模型创建和字段访问0.5hA4
任务 B:业务逻辑层(B1 - B4)
任务 ID任务描述预估工时依赖
B1定义 AI宝宝辅食搭配Service 类0.5hA5
B2实现 generateData 方法签名0.5hB1
B3实现 Mock 数据生成逻辑1hB2
B4单元测试:验证 Service 数据生成0.5hB3
任务 C:UI 页面构建(C1 - C8)
任务 ID任务描述预估工时依赖
C1创建页面组件结构,添加 @Entry 和 @Component 装饰器0.5h无
C2实现 Header 区域(标题+返回按钮)0.5hC1
C3实现装饰性 Emoji 行0.25hC2
C4实现输入区域(月龄、过敏源、偏好)1hC3
C5实现"生成辅食"按钮0.25hC4
C6实现结果展示区域(食谱、食材、步骤、营养信息)2hC5, B4
C7实现状态管理(@State 变量绑定)0.5hC6
C8页面样式优化(颜色、圆角、间距)1hC7
任务 D:集成与配置(D1 - D3)
任务 ID任务描述预估工时依赖
D1在 apps.json 中注册应用配置0.25h无
D2验证路由跳转是否正确0.25hD1, C8
D3端到端集成测试1hD2

3.2 依赖关系图

A1 → A2 → A3 → A4 → A5
                        ↘
                    B1 → B2 → B3 → B4
                                    ↘
C1 → C2 → C3 → C4 → C5 → C6 → C7 → C8 → D1 → D2 → D3

3.3 并行执行策略

根据依赖关系图,我们可以并行执行以下任务链:

  • 链 1:A1 → A2 → A3 → A4 → A5(数据模型,独立进行)
  • 链 2:B1 → B2 → B3 → B4(业务逻辑,依赖 A 链完成)
  • 链 3:C1 → C2 → C3 → C4 → C5(页面 UI,可与 A 链并行)
  • 链 4:C6 → C7 → C8(UI 完整,依赖 B 链完成)
  • 链 5:D1 → D2 → D3(集成,依赖所有链完成)

3.4 原子化收益

通过原子化分解,我们获得了以下收益:

  1. 精确估算:每个原子任务不超过 2 小时,估算误差小于 15%
  2. 并行度最大化:UI 开发与数据层开发完全并行,缩短总工期 40%
  3. 风险隔离:单个任务失败不会阻塞整个项目
  4. 可追踪性:每个任务都有明确的完成标准和验收标准

四、审批阶段(Approve)

审批阶段是质量保障的关键环节。在每个原子任务完成后,我们执行严格的代码审查和质量门控。

4.1 代码审查标准

针对 ArkTS 的特殊语法约束,我们制定了以下审查清单:

语法合规审查
检查项描述严重程度
无 any/unknown所有类型必须显式标注,禁止使用 any 或 unknown阻断
无解构赋值禁止使用解构赋值解构,改用临时变量阻断
无 Function.bind禁止使用 bind,遵循传统 OOP 的 this 语义阻断
无 in 运算符检查对象成员使用 instanceof 替代阻断
无索引签名数据容器使用数组而非索引签名阻断
无 as const字面量使用显式类型标注阻断
箭头函数禁止函数表达式,全部使用箭头函数建议
类字段声明在类声明内直接声明字段,不在构造函数中声明阻断
质量审查
检查项描述严重程度
代码可读性变量命名清晰、单一职责原则建议
组件粒度组件是否过大,是否需要拆分建议
状态管理@State 使用是否合理,是否有不必要的状态建议
性能考量是否有不必要的重复渲染建议
错误处理边界情况是否考虑建议

4.2 实际审查案例

在审查 AI宝宝辅食搭配Page.ets 时,我们发现了以下问题并进行了修正:

问题 1:索引访问对象字段

原始代码使用了 inputData['月龄'] 的方式访问对象字段,这在 ArkTS 中是不允许的。

// ❌ 不符合规范:通过索引访问对象字段
.onChange((val: string) => { this.inputData['月龄'] = val })

虽然 ArkTS 不支持通过 obj.field 语法动态添加字段,但在 Record<string, Object> 类型上使用索引访问是允许的(因为 Record 是 TypeScript 实用类型中的允许特例)。但最佳实践是使用明确的键名。经过审查,我们确认了这种方式在 Record<string, Object> 类型上是安全的,因为 Record<K, V> 的索引表达式 rec[index] 的类型为 V | undefined。

问题 2:条件渲染中的空值检查

// ✅ 符合规范:显式检查 null
if (this.showResult && this.resultData !== null) {
  // 渲染结果
}

这里必须显式检查 this.resultData !== null,因为 ArkTS 不支持 if (this.resultData) 这种隐式类型转换。

4.3 审批流程

开发者提交 PR → 自动化检查(语法/类型检查通过)
  → 代码审查(Code Review)→ 审查通过
  → 质量门控(Quality Gate)→ 通过
  → 合并到主分支

每个审批环节都有明确的通过标准,环环相扣,确保代码质量。


五、自动化执行阶段(Automate)

自动化执行阶段是实际编码实现的过程。我们严格按照原子化任务分解和架构设计进行开发。

5.1 环境搭建

首先确认项目依赖配置。项目使用 HarmonyOS 6.0.1 版本,模块级依赖配置如下:

// 文件路径: entry/oh-package.json5
{
  "name": "entry",
  "version": "1.0.0",
  "description": "Please describe the basic information.",
  "main": "",
  "author": "",
  "license": "",
  "dependencies": {}
}

项目本身不依赖第三方库,所有功能基于 HarmonyOS 原生 API 实现。

5.2 数据模型层实现

数据模型层的实现是首要任务。在 ArkTS 中,类定义需要特别注意语法约束。

关键实现细节:

  1. 字段声明:所有字段必须在类声明内部直接声明,而不是在构造函数中声明。这是因为 ArkTS 不支持在构造函数中声明类字段。

  2. 类型标注:每个字段都必须有显式类型标注。string[] 用于表示字符串数组,string 用于表示单个字符串值。

  3. 初始化:所有字段都需要初始值,ArkTS 不支持确定性赋值断言(let v!: T)。

  4. 构造函数:构造函数中再次初始化所有字段,这种做法虽然有些冗余,但提高了代码的可读性和确定性,也便于后续维护者理解。

5.3 业务逻辑层实现

业务逻辑层的 generateData 方法设计为可扩展的。在 MVP 阶段,我们使用 Mock 数据;在后续迭代中,可以无缝替换为真实的 AI API 调用。

设计模式:策略模式

// 后续可以这样扩展:
export class AI宝宝辅食搭配Service {
  private strategy: GenerationStrategy

  constructor(strategy?: GenerationStrategy) {
    this.strategy = strategy || new MockGenerationStrategy()
  }

  generateData(input: Record<string, Object>): AI宝宝辅食搭配Data {
    return this.strategy.generate(input)
  }
}

// 定义策略接口
interface GenerationStrategy {
  generate(input: Record<string, Object>): AI宝宝辅食搭配Data
}

// Mock 策略实现
class MockGenerationStrategy implements GenerationStrategy {
  generate(input: Record<string, Object>): AI宝宝辅食搭配Data {
    let result: AI宝宝辅食搭配Data = new AI宝宝辅食搭配Data()
    let age_monthsVal: string = String(input['age_months'] || '')
    result.recipes = ['示例数据1', '示例数据2', '示例数据3']
    result.weekly_plan = '生成结果:' + age_monthsVal
    // ... 更多数据
    return result
  }
Logo

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

更多推荐