鸿蒙 Flutter 项目的数据模型设计:Ingredient、Dish、Wish 怎么拆
适合谁看正在设计内容型应用数据模型的人想理解食材、菜品、愿望单这三层对象关系的人想从模型反推页面结构的人问题背景数据模型设计最容易犯的错就是把“内容实体”和“用户动作”混在一起。例如把食材和菜品当成同一层把愿望单直接当作菜品收藏这样一来页面职责和推荐逻辑都会被拖乱。项目中的真实场景食界探味当前的核心模型文件主要在app/lib/data/models/ingredient.dartapp/lib/data/models/dish.dartapp/lib/data/models/wish.dartapp/lib/data/models/collection_entry.dart而如果从鸿蒙场景往回看这几个模型还会继续影响app/lib/core/platform/intent_navigation_channel.dartapp/ohos/entry/src/main/ets/entryability/InsightIntentExecutorImpl.etsapp/ohos/entry/src/main/ets/formability/核心实现如果这篇只讲“模型字段分别是什么”其实还是不够像教程。更值得讲的是为什么这三个对象的拆法正好有利于承接鸿蒙里的系统入口、卡片和原生直达参数。一、Ingredient是入口层对象它更像“探索起点”而不是内容终点Ingredient当前关注的是食材名图片国家旗帜关联吃法数量顶部筛选标签这说明它代表的是“从什么食材开始探索”不是一道具体菜。这类对象的好处是它天然适合被首页、搜索、食材总览页消费它也适合被鸿蒙系统入口映射成更宽泛的探索入口而不是某个具体详情页换句话说Ingredient更适合作为Flutter 页面里的一级探索对象HarmonyOS 入口里的“功能起点”二、Dish是内容消费层对象也是最适合被系统直达的核心内容实体Dish当前包含菜品名国家风味标签灵魂说明核心食材图片用户收藏和已吃过状态这说明它才是项目里最核心的内容对象。而且从鸿蒙角度看它还有一个额外价值它最适合和dishId这种系统直达参数绑定当前项目里原生入口层会校验dish_detail是否带dishIdFlutter 路由层最终把它映射到/dish/:id这其实反过来证明了模型拆得是合理的如果Dish不是一个清楚、稳定的核心对象系统直达入口就很难长期成立。三、Wish是需求表达层对象它本质上不是内容而是用户意图Wish并不是内容本身而是用户想看什么为什么想看当前实现到什么状态所以它有WishTypeWishStatusWishReasonType这种结构化字段。它和Dish、Ingredient最大的区别就在于前两者是内容实体Wish是用户想要什么内容的表达这类对象拆出来之后后面无论是AI 助手理解用户意图卡片推荐选题系统入口回流到许愿单场景都会更容易围绕稳定语义工作。四、收藏记录又是另一层这说明“用户动作”没有反向污染内容实体CollectionEntry说明项目没有把“收藏动作”和“Dish 模型本体”完全绑死。它额外携带收藏元数据嵌套Dish这是比较合理的。因为它说明项目没有把内容本体用户动作元数据强行揉成一个对象。这对鸿蒙场景也有好处因为卡片推荐、Intent 跳页、AI 检索更适合围绕稳定内容实体工作收藏、已吃过、支持愿望这些用户动作则可以按交互层单独扩展五、为什么这个拆法和鸿蒙入口、卡片、AI 都更容易协作如果把三个对象再放回整个项目里看会更清楚Ingredient适合作为探索入口对象Dish适合作为详情直达对象Wish适合作为用户需求表达对象这恰好和鸿蒙里常见的三类场景形成对应系统入口想打开某个功能页时更适合围绕Ingredient或功能语义组织系统入口想直达某个具体内容时更适合围绕DishdishId想把用户长期需求沉淀下来时更适合围绕Wish所以这套模型拆法不是只服务 Flutter 页面它实际上也在帮 HarmonyOS 场景建立稳定对象边界。关键代码位置app/lib/data/models/ingredient.dartapp/lib/data/models/dish.dartapp/lib/data/models/wish.dartapp/lib/data/models/collection_entry.dart鸿蒙侧实现这一篇重点在 Flutter 数据层。不过模型拆得越清楚后面无论是卡片推荐Intent 跳页AI 工具调用都更容易围绕稳定内容对象工作。例如当前鸿蒙侧入口链之所以能保持简单很大程度上也是因为它只需要处理pageIddishId而不用去理解一团混杂的数据结构。Flutter 侧实现Flutter 侧当前的模型分层非常有利于页面组织食材页围绕Ingredient详情页围绕Dish愿望单页围绕Wish不会出现一层模型撑全项目的情况。而且这也让路由、状态管理和平台边界层都更容易保持清楚路由层知道详情页最终围绕Dish状态层知道许愿箱围绕Wish平台入口层知道dishId指向的是哪类核心对象常见坑把食材和菜品混成同一个模型把用户愿望和收藏状态直接塞回Dish模型字段只为当前页面服务缺少长期语义只看接口结构不看产品里的对象关系为了配合某个鸿蒙入口临时加字段最后把模型越改越像一层传参容器原生入口和 Flutter 路由都能改模型语义导致对象边界越来越模糊可复用模板class Wish { final String id; final String title; final WishType type; final WishStatus status; }Ingredient探索入口对象 Dish内容详情对象 Wish用户意图对象 系统直达优先围绕稳定对象 id而不是围绕临时页面状态本篇总结Ingredient、Dish、Wish分开核心是三者在产品里承担的角色根本不同这套拆法不只服务 Flutter 页面也让鸿蒙里的系统直达、卡片、AI 工具都能围绕稳定对象工作模型是否清晰决定后面的页面、路由、平台入口和原生能力协作能不能稳