当前位置: 首页 > news >正文

【HarmonyOS 6.1 全场景实战】《灵犀厨房》实战之补充【架构进化】灵犀厨房四层分层设计:给鸿蒙 App 搭一副坚不可摧的骨架

【架构进化】灵犀厨房四层分层设计:给鸿蒙 App 搭一副坚不可摧的骨架

摘要:当你写完购物清单,看着pages目录下横七竖八的十几个文件,是不是觉得《灵犀厨房》越来越像一间堆满食材却找不到盐的厨房?今天我们不写具体功能,而是拿起“架构的手术刀”,对整个项目做一次深度的分层重构。在这篇文章中,我会用“四层装甲车”的比喻,带你彻底搞懂 UI → ViewModel → Business → Services → Foundation 的依赖关系;同时结合 HarmonyOS 6.1.0 的@ObservedV2@ComponentV2等新特性,绘制出一张攻守兼备的架构蓝图。读完你会发现——好的架构,会让未来的每一行代码都写在正确的位置上。


引言与系列定位

在上一篇文章(第 10 篇)中,我们顺利地把散落的勾选食材聚合成了一张漂亮的分组购物清单。但当我们得意地审视项目目录时,一个危险的信号出现了:pages/Index.ets里竟然同时揉杂了推荐算法、状态管理、甚至还有一段临时硬编码的模拟数据。这就像把菜刀、砧板、调料瓶全都丢进同一个水槽——看似方便,一旦要加新功能,整个厨房都会乱套。

所以,在应用正式上架申请成功后,我们将向 Health Kit 健康数据发起冲锋前,不过现在我们必须先停一停,为《灵犀厨房》做一次彻底的“架构手术”。本文将交付一份可落地、可扩展的四层分层架构 v2.0,它将彻底解决以下痛点:

  • 代码耦合严重,改一个 UI 却触发了业务逻辑崩溃
  • 状态管理随心所欲,@State、@Link、@Provide 满天飞
  • 模拟数据和真实服务混杂,想接入 Health Kit 都无从下手

读完之后,你会清晰地知道:什么样的代码该放进business/,什么样的文件能直接触碰@kit.HealthKit,以及如何用 ViewModel 像胶水一样把 UI 与业务优雅粘合。


核心原理与底层机制深度解读

要理解这版架构的精髓,我们不妨把《灵犀厨房》想象成一辆四层装甲车(图 1):

  1. 外挂装甲(UI 层):负责抵挡用户的点击与滑动,只关心“长什么样”,绝不让一枚子弹穿透到内部。
  2. 火控计算机(ViewModel 层):接收 UI 的指令,计算并组织需要用到的数据,但它不扣扳机。
  3. 弹药系统(Business 层):真正的业务规则所在,例如“从 10 道菜里筛出 4 道不辣且低于 500 大卡的推荐”。
  4. 引擎与底盘(Services 层):封装最底层的系统能力,比如调用 Health Kit、数据库、通知推送。它们只提供动力,不关心你往哪儿开。
  5. 零件图纸(Foundation 层):纯粹的数据结构,像RecipeUserPreference,是全体模块的唯一语言。

在 HarmonyOS 中,这种分层之所以能生效,靠的是依赖倒置V2 状态管理的精确配合。@ObservedV2装饰的 ViewModel 类就像指挥塔,通过@Trace属性把“弹药状态”实时同步给 UI 层的雷达屏幕。而 Business 层则完全不知道 UI 的存在,它只是对着空气(接口)开火。这就保证了当我们后续将模拟厨电换成真实分布式软总线时,只需要替换 Business 层的一个模块,UI 层连一个像素都不会抖动。


关键知识点详解

面对中大型鸿蒙应用,架构选型通常有三条路:

架构模式核心思想优点缺点《灵犀厨房》适用性
MVVM 轻架构每个页面配一个 ViewModel,Model 层直接操作数据简单、上手快业务逻辑容易在 ViewModel 中膨胀,跨页面复用困难❌ 前期可用,后期难以维护购物清单、健康分析等多模块交互
VIPER/Clean Architecture严格的 Interactor、Presenter、Router 分离高度解耦,可测试性极强模板代码过多,对中小型应用性价比低❌ 团队只有你一人,过度设计
四层分层架构(本文方案)UI-ViewModel-Business-Services 清晰切分,Foundation 作为数据基座兼具清晰边界与务实灵活,符合鸿蒙组件化思想需要严格遵循依赖规则,初期需要一定学习成本最佳平衡点,完美适配《灵犀厨房》的功能增长曲线

同时,对比一下状态管理方案的进化:

方案装饰器性能类属性观测跨组件共享《灵犀厨房》v2.0 选型
V1 状态管理@State@Link@Provide一般,易触发冗余渲染不支持类属性级监听复杂且需手动@Provide/@Consume❌ 已在第 9 篇被 V2 替代
V2 状态管理@ObservedV2@Trace@Local@Param精准更新,性能提升明显@Trace可监听类成员变量通过@Provider()/@Consumer()简洁优雅✅ 本次架构重构的唯一选择

架构设计 / 核心逻辑图解

话不多说,上“骨相图”。下面这张 Mermaid 关系图,揭示了《灵犀厨房》v2.0 的五层依赖与四大数据流。

Foundation 层

Services 层

Business 层

UI 层 (pages/components)

ViewModel 层

MainContainer
Tab导航

HomeViewModel

RecipeDetailPage

IngredientViewModel

ShoppingListPage

ShoppingListVM

HealthDashboard

HealthDashboardVM

KitchenDevice

KitchenDeviceVM

ProfilePage

ProfileViewModel

RecommendEngine

RecipeManager

ShoppingList

NutritionAnalyzer

KitchenDeviceSimulator

HealthServiceHelper

NotificationHelper

RelationalStoreHelper

Recipe

UserPreference

MockData

架构师解读:注意所有依赖箭头都是从上往下,且 Services 层绝不反向引用 Business 或 UI。这就奠定了“上层易变,底层稳定”的演化基础。

再来看一条最典型的推荐数据流是如何在四层间起舞的:

MockDataRecommendEngineHomeViewModelHomeTabContentMockDataRecommendEngineHomeViewModelHomeTabContent"refreshByPreference()""isLoading = true""getRecommendations(pref, 4)""读取全量菜谱""忌口过滤 + 卡路里筛选""多维加权评分 (偏好+季节+去重)""4条推荐Recipe数组""recommendedRecipes = result, isLoading = false""Trace 触发精准渲染"

实战:分层架构的落地与模块化搬迁

架构图再漂亮,不落地就是一张废纸。我们根据这张蓝图,对《灵犀厨房》的工程目录做了一次精准的“器官移植”。

Step 1:重新定义 Foundation 层——让数据模型成为单一真相源

首先,把散落在各处的FoodItemRecipe等类型统一收口到foundation/model/。这里不得存在任何import router@kit,只能有纯血统的classinterface

// foundation/model/Recipe.etsexportclassRecipe{id:number=0name:string=''cover:Resource=$r('app.media.default_cover')ingredientItems:IngredientItem[]=[]tags:string[]=[]calories:number=0// ...}exportclassIngredientItem{name:string=''amount:string=''isChecked:boolean=false}

变化点解读:相比第 4 篇时model/下的混乱,现在的 Foundation 层连一个@State都不允许出现。它就像国际度量衡局,只负责定义“米”和“千克”,绝不参与买卖。

Step 2:提取 Business 层——把“智慧大脑”独立出来

将原来嵌在Index.ets中的推荐逻辑,重构为business/RecommendEngine.ets的单例。同样的手术也用在菜谱管理、购物清单分组上。

// business/RecommendEngine.etsimport{Recipe}from'../foundation/model/Recipe'import{UserPreference}from'../foundation/model/UserPreference'import{MockData}from'../foundation/model/MockData'classRecommendEngine{getRecommendations(pref:UserPreference,count:number):Recipe[]{// 1. 从 MockData 全量获取letcandidates=MockData.getAllRecipes()// 2. 忌口过滤candidates=candidates.filter(r=>!r.tags.some(tag=>pref.allergies.includes(tag)))// 3. 多维度评分排序...// 4. 去重并返回returncandidates.slice(0,count)}}exportconstrecommendEngine=newRecommendEngine()

核心点解读:现在,即便我们把MockData替换为远端 API 或 Health Kit 实时数据,也只需在这个黑盒内部修改。ViewModel 和 UI 完全无感。

Step 3:固实 ViewModel 管道——用 @ObservedV2 粘合一切

每个复杂页面搭配专属 ViewModel,它只负责做两件事:调用 Business 层获取数据,以及用 @Trace 属性驱动 UI 刷新

// viewmodel/HomeViewModel.etsimport{recommendEngine}from'../business/RecommendEngine'import{Recipe}from'../foundation/model/Recipe'@ObservedV2exportclassHomeViewModel{@TracerecommendedRecipes:Recipe[]=[]@TraceisLoading:boolean=falserefreshByPreference(pref:UserPreference){this.isLoading=truethis.recommendedRecipes=recommendEngine.getRecommendations(pref,4)this.isLoading=false}}
Step 4:UI 层瘦身——用 @ComponentV2 + @Local 拥抱 ViewModel

MainContainer内的每个 Tab 都变成了一个干净的@ComponentV2,仅持有自己的 ViewModel 实例,并把它通过@BuilderParam或组件树向下传递。

// pages/MainContainer.ets 中 HomeTab 的片段@ComponentV2struct HomeTabContent{@LocalhomeVM:HomeViewModel=newHomeViewModel()build(){Column(){if(this.homeVM.isLoading){LoadingProgress()}else{List(){ForEach(this.homeVM.recommendedRecipes,(recipe:Recipe)=>{ListItem(){RecommendCard({recipe:recipe})}})}}}}}

变化点解读:UI 层彻底扔掉了所有if-else业务判断,它的build()方法就像一个哑巴服务员,只负责端盘子,不负责炒菜。

Step 5:Services 层预留接口——为 Health Kit 腾出空间

我们在services/HealthServiceHelper.ets中预埋了一个桩(Stub),它目前返回模拟数据,但完整实现了calculateNutritionBudget所需的一切签名。第 12 篇接入真实 Health Kit 时,只需要填充其内部实现。


运行与结果验证

现在我们执行一次全量编译,并通过 DevEco Studio 的依赖分析插件查看模块耦合度。

期望输出(在 Log 中通过代码显式打印,验证分层是否生效):

[灵犀厨房-架构] 当前首页推荐引擎已独立加载,依赖链: UI→HomeViewModel→RecommendEngine→MockData [灵犀厨房-架构] 未检测到 business 层对 @kit.HealthKit 的直接引用,分层规则校验通过。

日志解读
这串日志虽然是我们刻意埋下的“架构哨兵”,但它真实地反映出四层分层的约束力。当我们后续新增 HealthKit 接入时,如果发现编译报错Cannot find module '@kit.HealthKit'出现在business/目录下,就说明有人试图越界开火,必须立刻修正。


本阶段总结与下篇预告

今天,我们没有为《灵犀厨房》添加任何一个用户可见的新按钮,但却完成了整个项目最昂贵的投资——架构。我们用四层装甲车的模型,把脆弱的代码堆砌重构为 UI、ViewModel、Business、Services、Foundation 五大清晰阵地,并依托 HarmonyOS 6.1.0 的 V2 状态管理,实现了编译期的依赖约束和运行时的精准渲染。

地基已经夯实到足以承载摩天大楼。这篇作为《灵犀厨房》架构补充篇。在后续等应用完成上架后,我们将正式驾驶这辆装甲车,冲进 【数据打通】访问 Health Kit 获取健康数据的战场。届时,你会看到HealthServiceHelper如何从 Stub 蜕变成真正的健康数据管道,而你的菜谱推荐也将第一次拥有卡路里和步数的科学依据。我们下期见!


📚 本系列持续更新中:下一篇,我们将完成【营养分析引擎】计算个性化卡路里建议新篇章,敬请期待。

🔗专栏入口:[《从0到1开发灵犀厨房App》合集] | ⭐源码:Gitee 仓库


http://www.jsqmd.com/news/824055/

相关文章:

  • 从大语言模型到文本检测:Awesome资源清单与实战指南
  • 基于GitHub Actions与OpenAI API构建AI自动编程工作流实践
  • 用Arduino和MAX7219点亮你的第一个8x8 LED点阵屏(附完整代码与接线图)
  • AbMole丨Apigenin:天然黄酮化合物在氧化应激中的应用
  • 基于Web前端技术构建桌面虚拟宠物:从原理到实践
  • 家庭NAS平替方案:手把手教你搭建基于旧电脑的简易文件共享中心(支持手机平板访问)
  • 从数据云到ArcGIS:一站式掌握DEM影像的获取、拼接与裁剪实战
  • AWD Watchbird PHP WAF终极实战指南:深度解析高性能Web应用防护方案
  • PPTAgent终极指南:5分钟搞定专业演示文稿的AI智能生成方案
  • FModel:解锁虚幻引擎游戏资源的终极工具指南
  • 两个清华学霸 41 岁第二次创业,10 年把华为耳机里的“中国芯“做成了 800 亿市值
  • 你的APK被加固了吗?用这个Python脚本ApkTool.py快速检测应用加固与引擎类型
  • 5分钟快速上手:Python大麦网自动抢票脚本终极指南
  • FGO-py完整指南:如何用Python自动化你的《命运/冠位指定》游戏体验
  • 书匠策AI到底是什么?用科普的方式拆解这个毕业论文“外挂“的底层逻辑
  • AbMole丨CL 316243:β3-肾上腺素受体激动剂,在代谢调控与能量消耗研究中的应用
  • DsHidMini终极方案:让PS3手柄在Windows系统焕发第二春的完全指南
  • OpenClaw会话上下文管理:构建智能多轮对话系统的核心引擎
  • Wwise音频工具完全指南:3步轻松解包和修改游戏音频文件
  • AI文档智能审查:从NLP原理到企业级部署实战
  • 2026成都民宿固装酒店家具定制厂家,源头工厂测量设计安装一站式 - 企业推荐师
  • 开源剧本创作神器Trelby:让专业编剧变得像写邮件一样简单
  • 风控在链路中的攻防(1)——交易发起端:用户侧的对抗
  • 避开版本坑!编译ADI GitHub工程(如ADRV9009)前必看的IP核与Vivado版本检查指南
  • Claude与Figma智能协作:基于MCP协议的设计自动化实践
  • 三步快速解锁网盘高速下载:终极直链解析工具完整指南
  • 卡梅德生物技术快报|骆驼纳米抗体:从原核表达、高通量测序到分子对接全流程实现
  • 构建系统性研究者技能库:从知识管理到开源协作实践
  • 20252816 2025-2026-2 《网络攻防实践》第九次作业
  • qt-QSchematic-3.0.3.zip