设计持久化层
问题
如何设计统一的数据持久化层?
答案
Repository 模式
实现
protocol UserRepository {
func getUser(id: String) async throws -> User
func getUsers() -> AsyncStream<[User]>
}
class UserRepositoryImpl: UserRepository {
private let remote: UserRemoteDataSource
private let local: UserLocalDataSource
// 网络优先,缓存兜底
func getUser(id: String) async throws -> User {
do {
let user = try await remote.fetchUser(id: id)
try await local.save(user)
return user
} catch {
// 网络失败,返回缓存
if let cached = try? await local.getUser(id: id) {
return cached
}
throw error
}
}
// 响应式数据流
func getUsers() -> AsyncStream<[User]> {
AsyncStream { continuation in
// 先返回本地数据
Task {
let cached = try? await local.getAllUsers()
if let cached { continuation.yield(cached) }
// 再拉取远程数据
let remote = try? await remote.fetchUsers()
if let remote {
try? await local.saveAll(remote)
continuation.yield(remote)
}
continuation.finish()
}
}
}
}
缓存策略
| 策略 | 适用场景 |
|---|---|
| Cache First | 列表页、不要求实时 |
| Network First | 详情页、需要最新数据 |
| Stale While Revalidate | 先展示缓存,后台更新 |
| Network Only | 支付、下单等关键操作 |
常见面试问题
Q1: SSOT 是什么?
答案:Single Source of Truth,单一数据源。所有数据变更都经过 Repository,确保 UI 读取的数据来源一致,避免多处缓存导致数据不一致。