第 19 课2026.07.29
适用场景:同一页面需要切换真实服务、测试服务或不同数据源,同时保持页面代码不变
第 19 课:接口抽象与可替换数据服务
- 日期:2026-07-29
- 课程序号:第 19 课
- 知识点:ArkTS 接口、依赖抽象、可替换的数据服务实现
- 适用场景:同一页面需要切换真实服务、测试服务或不同数据源,同时保持页面代码不变
承接上一课的数据服务拆分:上一课把请求逻辑移出页面;本课再用接口约定服务能力,让页面依赖稳定的方法签名,而不是依赖某个具体实现。
核心概念
接口只描述“能做什么”,实现类负责“具体怎么做”:
text
页面 -> MessageService 接口 -> LocalMessageService 具体实现
\-> 测试实现或网络实现queryMessages(): Promise<string[]> 是双方共同遵守的契约。只要新实现满足这个签名,页面就可以替换数据源,而不需要修改加载状态和 UI 渲染逻辑。
最小 ArkTS / ArkUI 示例
ts
interface MessageService {
queryMessages(): Promise<string[]>;
}
class LocalMessageService implements MessageService {
queryMessages(): Promise<string[]> {
return Promise.resolve(['系统通知', '学习提醒']);
}
}
@Entry
@Component
struct MessagePage {
private messageService: MessageService = new LocalMessageService();
@State loading: boolean = false;
@State items: string[] = [];
aboutToAppear(): void {
this.loadMessages();
}
async loadMessages(): Promise<void> {
this.loading = true;
try {
this.items = await this.messageService.queryMessages();
} finally {
this.loading = false;
}
}
build() {
Column({ space: 12 }) {
if (this.loading) {
Text('加载中...')
} else {
ForEach(this.items, (item: string) => {
Text(item)
}, (item: string) => item)
}
}
.width('100%')
.padding(20)
}
}页面字段的类型是 MessageService,而不是 LocalMessageService。这表示页面只使用接口承诺的能力;数据来自本地、网络还是测试数据,由传入的具体实现决定。
3~5 分钟练习
新增一个 EmptyMessageService:
- 实现
MessageService接口。 queryMessages()返回空数组。- 把页面中的服务替换为该实现,观察列表变为空。
参考答案
ts
class EmptyMessageService implements MessageService {
queryMessages(): Promise<string[]> {
return Promise.resolve([]);
}
}页面中只替换初始化语句:
ts
private messageService: MessageService = new EmptyMessageService();页面的生命周期、状态更新和 UI 代码均无需改变,这就是依赖接口带来的可替换性。
与上一课的联系
上一课确定了“页面负责状态与渲染,服务负责取数”的职责边界;本课用接口进一步固定这条边界,使具体数据服务可以替换。下一步可以学习为数据服务编写简单的单元测试,验证成功结果和失败行为。