鸿蒙游戏中的 Service 层应该怎么拆?
本文探讨了鸿蒙游戏开发中Service层的正确拆分方法。作者指出常见误区是将Service层当作工具集合,导致代码臃肿混乱。正确的做法是将Service层定位为"业务调度中心",按业务领域拆分(如PlayerService、TaskService等),每个Service专注单一职责,不直接操作UI。文章提出六层架构方案:核心业务Service→领域细化→流程调度→AI接入→网络


大家好,我是 子玥酱,一名长期深耕在一线的前端程序媛 👩💻。曾就职于多家知名互联网大厂,目前在某国企负责前端软件研发相关工作,主要聚焦于业务型系统的工程化建设与长期维护。
我持续输出和沉淀前端领域的实战经验,日常关注并分享的技术方向包括 前端工程化、小程序、React / RN、Flutter、跨端方案,
在复杂业务落地、组件抽象、性能优化以及多端协作方面积累了大量真实项目经验。
技术方向:前端 / 跨端 / 小程序 / 移动端工程化
内容平台:掘金、知乎、CSDN、简书
创作特点:实战导向、源码拆解、少空谈多落地
文章状态:长期稳定更新,大量原创输出
我的内容主要围绕 前端技术实战、真实业务踩坑总结、框架与方案选型思考、行业趋势解读 展开。文章不会停留在“API 怎么用”,而是更关注为什么这么设计、在什么场景下容易踩坑、真实项目中如何取舍,希望能帮你在实际工作中少走弯路。
子玥酱 · 前端成长记录官 ✨
👋 如果你正在做前端,或准备长期走前端这条路
📚 关注我,第一时间获取前端行业趋势与实践总结
🎁 可领取 11 类前端进阶学习资源(工程化 / 框架 / 跨端 / 面试 / 架构)
💡 一起把技术学“明白”,也用“到位”
持续写作,持续进阶。
愿我们都能在代码和生活里,走得更稳一点 🌱
文章目录
引言
很多人写鸿蒙游戏,一开始都会把 Service 层当成“工具层”:
UserService
GameService
DataService
看起来已经“分层”了,但只要项目一复杂,很快就会出现:
- Service 越写越大
- 方法越来越多
- 调用关系越来越乱
- AI / 多端接入困难
最后你会发现:
Service 不是没写,而是“没拆对”。
在 HarmonyOS 的架构中:
Service 层不是“工具集合”,而是“业务调度中心”。
下面我们讲清楚:
Service 层应该怎么拆,才能支持 AI + 多端 + 可扩展
一、先说结论
一个健康的 Service 层,必须做到:
1、单一职责(每个 Service 只做一类事)
2、面向业务(按功能拆,而不是按技术拆)
3、只操作 Store(不操作 UI)
4、作为数据流入口(UI / AI / 网络统一走这里)
如果你现在的 Service:
- 又请求网络
- 又改 UI
- 又写逻辑
那一定有问题。
二、最常见错误
“万能 Service”
export class GameService {
async fetchData() {}
movePlayer() {}
playSound() {}
login() {}
}
问题:
一个类 = 整个系统
后果:
- 不可维护
- 不可扩展
- 无法拆模块
按技术拆
NetworkService
StorageService
UtilService
问题:
没有业务语义
调用会变成:
networkService.fetch(...)
storageService.save(...)
代码越来越碎。
三、正确思路:按“业务能力”拆
正确结构
services
├─ player
│ └─ PlayerService
├─ task
│ └─ TaskService
├─ battle
│ └─ BattleService
├─ ai
│ └─ AIService
原则:
一个 Service = 一个业务领域
四、第一层拆分:核心业务 Service
示例:PlayerService
export class PlayerService {
move(dx: number) {
gameStore.dispatch({
type: 'MOVE_PLAYER',
payload: dx
})
}
takeDamage(value: number) {
gameStore.dispatch({
type: 'DAMAGE',
payload: value
})
}
}
特点:
- 只做“玩家相关逻辑”
- 不关心 UI
- 不直接请求网络
示例:TaskService
export class TaskService {
acceptTask(taskId: string) {
gameStore.dispatch({
type: 'ACCEPT_TASK',
payload: taskId
})
}
completeTask() {
gameStore.dispatch({
type: 'COMPLETE_TASK'
})
}
}
清晰、独立。
五、第二层拆分:领域内部再细化
当某个 Service 变大:
错误
PlayerService(1000行)
正确
player
├─ PlayerMoveService
├─ PlayerCombatService
├─ PlayerStateService
示例
export class PlayerCombatService {
attack() {
gameStore.dispatch({ type: 'ATTACK' })
}
}
好处:
- 职责更清晰
- 更容易维护
六、第三层:Service 调用关系
错误:随意调用
taskService.complete()
playerService.addScore()
battleService.end()
没有统一入口。
正确:由“调度 Service”统一
export class GameFlowService {
completeTask() {
taskService.completeTask()
playerService.addScore(10)
battleService.end()
}
}
本质:
流程统一调度
七、第四层:接入 AI
AI 不应该直接操作 Store。
错误
gameStore.dispatch({ type: 'ADD_SCORE' })
正确:AI → Service
class NPCAgent {
decide() {
return {
action: 'COMPLETE_TASK'
}
}
}
调用 Service
if (action === 'COMPLETE_TASK') {
gameFlowService.completeTask()
}
本质:
AI 通过 Service 控制系统
八、第五层:接入网络
错误
UI → fetch
正确
Service → Network
示例
export class RankService {
async fetchRank() {
const data = await httpClient.get("/rank")
gameStore.dispatch({
type: 'SET_RANK',
payload: data
})
}
}
Service 负责:
请求 + 转换 + 入 Store
九、第六层:支持多端
Service 不关心设备
dispatch(action) {
this.reduce(action)
this.sync(action)
}
Service 只负责:
触发 Action
Store 负责:
多端同步
十、最终 Service 架构
UI / AI / 网络
↓
Service
↓
Action
↓
Store
分层:
业务 Service(player / task)
↓
子 Service(combat / move)
↓
流程 Service(flow)
十一、判断你 Service 是否健康
有这些问题:
- 一个 Service 很大
- 方法杂乱
- UI 调用多个 Service
- AI 直接改 Store
正确状态:
职责清晰
调用简单
扩展容易
十二、常见错误总结
1、把 Service 当工具类
2、按技术拆(network / util)
3、Service 直接操作 UI
4、AI 绕过 Service
5、没有流程调度层
总结
鸿蒙游戏 Service 层的正确拆分方式:
按业务拆(player / task / battle)
+ 内部细化(move / combat)
+ 流程调度(flow)
+ AI / 网络统一入口
在 HarmonyOS 的架构中,Service 的角色是:
连接 UI、AI、网络和 Store 的“中枢层”。
最后:
Service 拆得好,你的游戏是系统;拆不好,只是一堆函数。
更多推荐
所有评论(0)