news 2026/8/4 11:53:02

山海万灵 HarmonyOS 文化知识实战(07):Repository Factory 的 HTTP/Mock/Fallback 切换

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
山海万灵 HarmonyOS 文化知识实战(07):Repository Factory 的 HTTP/Mock/Fallback 切换

文化图鉴的首页、探索页和馆长讲解页都要读取神兽、区域、展厅和学习卡。开发环境切换到 Mock 服务,或网络短暂不可用时,如果页面直接判断接口地址,很容易出现一套在线 UI、一套离线 UI。山海万灵把这种差异收敛在 Repository Factory 中:页面始终面向同一个ShanhaiRepository契约工作。

一、页面只取得领域仓库

ShanhaiAppViewModelFactory创建 ViewModel 时调用createShanhaiRepository()。页面和 ViewModel 不直接构造 HTTP 客户端,也不关心当前数据来自服务还是内置资料;它们只调用loadBootstraplistBeastslistRegionsexplainBeast等领域方法。

export function createShanhaiRepository(): ShanhaiRepository { return new FallbackShanhaiRepository( new HttpShanhaiRepository(), new MockShanhaiRepository() ) } export function createShanhaiAppViewModel(): ShanhaiAppViewModel { return new ShanhaiAppViewModel( createShanhaiRepository(), localProgressRepository, userProfileRepository ) }

这种边界让 UI 接收的始终是神兽、区域、展厅和学习卡等领域对象。服务端字段调整、Mock 数据补充和网络异常处理都留在仓库层,页面不会因此增加分支。

二、首次引导决定主通道

FallbackShanhaiRepository把 HTTP Repository 作为 primary,把 Mock Repository 作为 fallback。应用首次加载时先请求loadBootstrap();成功后将primaryReady置为真,后续的目录和概览读取走 HTTP 通道。请求失败则立即读取内置 Mock 数据,应用仍能打开图鉴和探索入口。

async loadBootstrap(): Promise<ShanhaiBootstrap> { try { const bootstrap = await this.primary.loadBootstrap() this.primaryReady = true return bootstrap } catch (_) { this.primaryReady = false return this.fallback.loadBootstrap() } } isUsingLocalFallback(): boolean { return !this.primaryReady }

项目自带 Mock API 联通后,首页会回读“在线同步 / 内容与图谱已同步”。这个提示来自同一套启动数据链路,说明当前启动流程已经取得 primary 返回的内容投影。

三、目录读取与细粒度动作分开处理

目录类方法包括listBeastslistRegionslistHallslistAiGuidesgetOverview。当首次引导已经建立 HTTP 主通道时,这些方法沿用该通道;首次引导未成功时则统一使用 Mock 数据。这样首页所需的基础目录在一次引导后有明确的数据来源。

场景仓库选择页面表现
bootstrap 请求成功HTTP Repository显示在线同步,加载远端目录和概览
bootstrap 请求失败Mock Repository保留本地图鉴目录与探索入口
讲解、学习卡、图谱推荐请求失败自动回退到 Mock Repository展示可读的本地讲解或学习卡,不让目标页面白屏

四、交互型请求具备二次回退

神兽讲解、学习卡、图谱推荐和发现动作属于进入页面后的细粒度请求。这些方法会在 HTTP 调用失败时把primaryReady改回假,并改由 Mock Repository 返回同形状的领域对象。页面不用捕获网络异常来拼装替代内容。

async explainBeast(beastId: string, topic: CuratorGuideTopic): Promise<AiGuideItem> { if (this.primaryReady) { try { return await this.primary.explainBeast(beastId, topic) } catch (_) { this.primaryReady = false } } return this.fallback.explainBeast(beastId, topic) } async listGraphRecommendations(nodeType: string, nodeId: string) { if (this.primaryReady) { try { return await this.primary.listGraphRecommendations(nodeType, nodeId) } catch (_) { this.primaryReady = false } } return this.fallback.listGraphRecommendations(nodeType, nodeId) }

回退状态会保留到下一次引导成功为止。用户继续阅读时,页面看到的是同一类神兽讲解、学习卡或推荐项,而不是错误页;这也是 Repository 契约统一的直接收益。

五、HTTP 映射层消化服务端字段

HTTP Repository 负责把接口响应映射为ShanhaiRepository使用的模型。新增字段或字段命名变化先在这里归一化,再由 Mock Repository 提供同一模型的本地版本。ViewModel 不依赖原始 JSON 字段,因此在线数据与 Mock 数据能使用同一套列表、详情和推荐组件。

这条约束也明确了边界:业务页只消费已经映射的领域对象;网络地址、请求失败和服务端字段兼容不进入 ArkUI 页面。需要接入新的服务时,先补齐 HTTP 映射和 Mock 对照数据,再让页面使用新增的领域字段。

以神兽详情为例,HTTP 数据除了基础名称和描述,还会映射区域、展厅、学习卡与图谱关联。Mock 数据采用相同的BeastItemAiGuideItemGraphRecommendationItem形状,详情页只按这些模型渲染。这样服务端将嵌套字段改为可选字段时,可以在 HTTP Repository 中补默认值或兼容转换;页面没有必要根据接口版本再增加条件判断。

async listLearningCards(beastId: string): Promise<BeastLearningCard[]> { if (this.primaryReady) { try { return await this.primary.listLearningCards(beastId) } catch (_) { this.primaryReady = false } } return this.fallback.listLearningCards(beastId) }

这里的回退边界也应保持明确:首次loadBootstrap失败时,本地目录成为启动数据;已经成功建立主通道后,讲解、学习卡、图谱推荐和发现动作会捕获单项失败并回退。目录读取不在这个细粒度捕获列表中,因而其异常策略不能由页面临时补齐。新增领域方法时,应先决定它属于启动目录还是交互动作,再选择对应的失败路径。

六、验收动作

可先启动项目自带的 Mock API,再启动应用并进入首页,确认在线同步提示与图鉴、探索入口都已加载。随后进入神兽详情并触发讲解、学习卡或图谱推荐;当交互请求不可用时,页面应继续显示本地可读内容。恢复服务后重新引导,目录读取重新进入 HTTP 通道。

验收时关注的是同一条操作链上的可观察结果:启动成功后首页展示在线同步状态;进入详情后,讲解或学习卡能够渲染;人为使该交互请求失败后,仍返回本地同类型内容;重新完成启动引导后,状态回到 HTTP 主通道。不要把其他页面的空状态当作回退成功,也不要把旧安装包的画面与新构建包混在一次结果中。

对于服务端演进,可增加一组 Mock 契约测试:给 HTTP 映射层一个字段缺失、空数组和未知枚举值的响应,确认输出仍能构造领域模型;再对 Mock Repository 做同一接口断言。两组结果一致,才能让页面组件在切换数据源后继续按既有模型工作。

网络请求接口的配置与调用方式可参考 HarmonyOS HTTP 请求指南。

七、把数据源切换限制在一个入口

Repository Factory 把 HTTP、Mock 与 Fallback 的组合固定在应用入口,ViewModel 取得的是稳定的领域接口。首次引导负责确定主通道,交互型请求负责在失败时回退,本地数据负责维持图鉴可读性。后续增加新接口时,只需扩展 Repository 契约、HTTP 映射与 Mock 对照数据,页面结构无需为数据源切换再写一遍。

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/8/4 11:51:18

前端工程师转型AI应用开发:一份包含收藏路线图与避坑指南的学习攻略

本文为前端工程师提供了转型AI应用开发的完整学习路线图&#xff0c;全程约8个月&#xff0c;涵盖Java后端基础、Python补课、LLM API集成、RAG知识库系统、Agent开发及AI工程化等关键内容。文章详细介绍了各阶段的学习重点、技术栈选择、以及常见陷阱的规避方法&#xff0c;旨…

作者头像 李华
网站建设 2026/8/4 11:48:39

解决中文用户名导致的软件启动失败问题

1. 问题背景与现象分析最近在技术社区看到不少用户反馈&#xff0c;安装某些软件时遇到启动失败的问题&#xff0c;特别是当系统用户名包含中文字符时。这种情况在Docker Desktop、Visual Studio Code等国际化软件中尤为常见。我自己在帮团队排查环境问题时也遇到过类似案例&am…

作者头像 李华
网站建设 2026/8/4 11:48:13

Deceive:英雄联盟、VALORANT和符文大地传说的智能隐身解决方案

Deceive&#xff1a;英雄联盟、VALORANT和符文大地传说的智能隐身解决方案 【免费下载链接】Deceive &#x1f3a9; Appear offline for League of Legends, VALORANT, and Legends of Runeterra. 项目地址: https://gitcode.com/gh_mirrors/de/Deceive 还在为游戏社交的…

作者头像 李华
网站建设 2026/8/4 11:37:29

3种革命性路径:让2015年前MacBook Pro重获新生的完全指南

3种革命性路径&#xff1a;让2015年前MacBook Pro重获新生的完全指南 【免费下载链接】OpenCore-Legacy-Patcher Experience macOS just like before 项目地址: https://gitcode.com/GitHub_Trending/op/OpenCore-Legacy-Patcher 你是否曾经看着自己那台性能依然强劲的2…

作者头像 李华
网站建设 2026/8/4 11:34:34

MyBatis-Plus自定义SQL与复杂查询实战指南

1. MyBatis-Plus 自定义 SQL 与复杂查询实战指南 在持久层框架选型中&#xff0c;MyBatis-Plus 因其对 MyBatis 的增强特性而广受欢迎。但当业务需求超出常规 CRUD 范围时&#xff0c;开发者常面临两个核心问题&#xff1a;如何优雅地实现自定义 SQL 语句&#xff1f;怎样高效处…

作者头像 李华