HarmonyOS 项目中如何拆分共用层与形态模型



子玥酱 (掘金 / 知乎 / CSDN / 简书 同名)

大家好,我是 子玥酱,一名长期深耕在一线的前端程序媛 👩‍💻。曾就职于多家知名互联网大厂,目前在某国企负责前端软件研发相关工作,主要聚焦于业务型系统的工程化建设与长期维护。

我持续输出和沉淀前端领域的实战经验,日常关注并分享的技术方向包括 前端工程化、小程序、React / RN、Flutter、跨端方案,

在复杂业务落地、组件抽象、性能优化以及多端协作方面积累了大量真实项目经验。

技术方向: 前端 / 跨端 / 小程序 / 移动端工程化 内容平台: 掘金、知乎、CSDN、简书 创作特点: 实战导向、源码拆解、少空谈多落地 **文章状态:**长期稳定更新,大量原创输出

我的内容主要围绕 前端技术实战、真实业务踩坑总结、框架与方案选型思考、行业趋势解读 展开。文章不会停留在"API 怎么用",而是更关注为什么这么设计、在什么场景下容易踩坑、真实项目中如何取舍,希望能帮你在实际工作中少走弯路。

子玥酱 · 前端成长记录官 ✨

👋 如果你正在做前端,或准备长期走前端这条路

📚 关注我,第一时间获取前端行业趋势与实践总结

🎁 可领取 11 类前端进阶学习资源 (工程化 / 框架 / 跨端 / 面试 / 架构)

💡 一起把技术学"明白",也用"到位"

持续写作,持续进阶。

愿我们都能在代码和生活里,走得更稳一点 🌱

文章目录

引言

HarmonyOS 项目中,为什么要拆「共用层」和「形态模型」

在 HarmonyOS 项目里,真正能复用的东西,其实非常有限

如果你把一个项目跑在:

  • 手机
  • 平板
  • PC
  • 甚至游戏窗口 / 多实例

你会发现一个很残酷的现实:

逻辑看起来一样,但模型几乎一定不一样。

所以在 HarmonyOS 中,正确的拆法不是:

「这段代码能不能复用?」

而是先想清楚:

哪些东西"不该知道设备形态"?
哪些东西"必须知道自己跑在哪"?

这就是共用层和形态模型的边界。

一、什么是真正的「共用能力层」

共用能力层只有一个标准:

它不应该关心:

  • 屏幕大小
  • 窗口是否可缩放
  • 是否支持多文档
  • 是否存在鼠标 / 键盘
  • 是否允许后台常驻

典型可以下沉为共用层的内容

这几类,在 HarmonyOS 上几乎永远成立

  • 网络请求(API / GraphQL / WebSocket)
  • 数据持久化(KV / RDB / 文件 IO)
  • 业务计算规则
  • 状态派生逻辑(非 UI)
  • 跨设备同步协议
  • 权限与能力判断封装

共用层的一个重要原则

共用层只输出"能力",不输出"行为"。

举个例子

错误的共用层设计:

ts 复制代码
// 不该出现在共用层
export function openDocument(id: string) {
  Router.pushUrl({
    url: 'pages/editor',
    params: { id }
  })
}

正确的共用层设计:

ts 复制代码
// common/document/DocumentRepository.ts
export class DocumentRepository {
  async load(id: string): Promise<Document> {
    // 只负责数据
  }

  async save(doc: Document) {
    // 只负责持久化
  }
}

"怎么打开、在哪打开、能不能多开"------一律不在共用层出现。

二、什么是「形态专属模型层」

这是很多 HarmonyOS 项目最容易偷懒、但后期最痛的地方

形态模型层解决的不是 UI,而是:

"这个形态下,业务是怎么运转的"

不同形态,模型关注点完全不同

手机 App 模型关心什么?
  • 单页面 / 栈式导航
  • 页面切换即上下文切换
  • 生命周期频繁
  • 强依赖前后台状态
PC 模型关心什么?
  • 多窗口 / 多文档并行
  • 文档是否脏(dirty)
  • 是否允许并排视图
  • 窗口最小化 ≠ 生命周期结束
游戏 / 强交互形态关心什么?
  • 帧循环
  • 输入源多样化
  • 状态常驻
  • UI 与逻辑高度解耦

你可以共用数据层,但你不可能共用模型层。

三、一个推荐的拆分结构(真实可用)

下面是我在 HarmonyOS PC 项目里比较稳定的一套结构

text 复制代码
src/
 ├── common/
 │    ├── network/
 │    ├── storage/
 │    ├── domain/
 │    │     ├── Document.ts
 │    │     └── User.ts
 │    └── service/
 │
 ├── app/
 │    ├── model/
 │    │     └── AppSessionModel.ts
 │    └── ui/
 │
 ├── pc/
 │    ├── model/
 │    │     ├── WorkspaceModel.ts
 │    │     └── DocumentWindowModel.ts
 │    └── ui/
 │
 └── game/
      ├── model/
      └── runtime/

关键点在于:

  • common 永远不 import app / pc
  • pc/model 可以组合 common
  • 模型之间允许策略不同,不强求一致

四、PC 形态下,一个"必须独立"的模型例子

PC 文档模型的核心,不是内容,而是「状态」

ts 复制代码
// pc/model/DocumentWindowModel.ts
export class DocumentWindowModel {
  constructor(
    private repo: DocumentRepository
  ) {}

  document: Document | null = null
  isDirty: boolean = false
  isActive: boolean = false

  async open(id: string) {
    this.document = await this.repo.load(id)
    this.isDirty = false
  }

  updateContent(content: string) {
    if (!this.document) return
    this.document.content = content
    this.isDirty = true
  }

  async saveIfNeeded() {
    if (this.document && this.isDirty) {
      await this.repo.save(this.document)
      this.isDirty = false
    }
  }
}

如果你把这个模型强行塞进手机 App:

  • 页面切换时你会丢状态
  • 多文档会变成噩梦
  • 后台恢复逻辑会失控

不是代码写得不好,是模型选错了形态。

五、一个判断标准:这段逻辑该放哪?

我给你一个非常好用的判断表:

问题
是否依赖窗口 / 页面数量 形态模型 共用层
是否依赖输入方式(鼠标 / 触控) 形态模型 共用层
是否只关心数据正确性 共用层 形态模型
是否涉及生命周期策略 形态模型 共用层
是否希望跨形态完全复用 共用层 形态模型

六、总结

HarmonyOS 的"统一",是能力层的统一,不是模型的统一。

相关推荐
试着2 小时前
【huawei】机试
华为·面试·机试·手搓代码
要做一个小太阳2 小时前
华为Atlas 900 A3 SuperPoD 超节点网络架构
运维·服务器·网络·华为·架构
Facechat2 小时前
鸿蒙开发入坑篇(九):本地数据库 (RDB) 深度解析
数据库·华为·harmonyos
2501_921930832 小时前
React Native 鸿蒙跨平台开发:LinearGradient 径向渐变
react native·react.js·harmonyos
2601_949593652 小时前
React Native 鸿蒙跨平台开发:LinearGradient 实战案例集
react native·react.js·harmonyos
阿钱真强道2 小时前
08 鸿蒙对接-jetlinks-official-protocol-不使用md5-不加时间戳
华为·harmonyos
2501_920931702 小时前
React Native鸿蒙跨平台跨平台阅读应用实现方案,包含书籍展示、分类筛选、搜索排序等功能模块,通过清晰的状态管理实现数据筛选与排序
react native·react.js·ecmascript·harmonyos
听麟2 小时前
HarmonyOS 6.0+ PC端多设备文件拖拽协同开发实战:手眼同行增强与分布式软总线深度应用
分布式·华为·harmonyos
kogorou0105-bit2 小时前
前端设计模式:发布订阅与依赖倒置的解耦之道
前端·设计模式·面试·状态模式