android - 如何在干净的架构中执行请求链?
问题描述
在我们的例子中,我需要在应用程序启动时执行请求链,例如
- 应用程序需要通过 gis 或 IP 地址检索位置
- 通过 http 按位置请求服务器列表
- 从我们得到的服务器列表中的服务器请求远程配置
我为每个项目创建一个数据层
class DefaultLocationRepository(
@LocateByGis gisLocationDataSource: LocationDataSource,
@LocateByIp ipLocationDataSource: LocationDataSource
): LocationRepository {
suspend fun locate(): Result<Location> {
....
}
}
class DefaultServerRepository(
remoteServerDataSource: RemoteServerDataSource
): ServerRepository {
suspend fun retrieve(location: Location): List<Server> {
}
}
class DefaultRemoteConfigRepository (
remoteConfigDataSource: RemoteConfigDataSource
): RemoteConfigDataSource {
suspend fun retrieve(server: List<Server>) {
}
}
我的问题是,链接这些任务的最佳实践是什么?我可以为每个操作创建一个用例
class LocateUseCase
class RetrieveServersUseCase
class RetrieveRemoteConfigUseCase
class MainViewModel: ViewModel() {
suspend fun start() {
locateUserCase().onSuccess {
retrieveServerUseCase(GetLocationUseCase()).onSuccess {
retrieveConfigServerUseCase(GetServerListUseCase()).onSuccess {
// balabala...
}
}
}
}
}
我觉得太丑了
我可以通过刀柄注入来做到这一点,存储库返回一个 Flow 而不是一个挂起函数调用,
class LocatonRepository() {
private var latestLocation: Location? = null
val location: Flow<Location> {
if (latestLocation != null) {
emit (latestLocation!!)
return@flow
}
dataSource.get().onSuccess { emit(it) }
}
}
// Modules
@InstallIn(Singleton::class::java)
@Module
class Modules {
@Provides
fun provideLocation(repository: LocationRepository): Flow<Location> =
repository.location
}
当 Flow 注入 ServerList 时,服务器存储库可以通过以下方式触发定位位置请求location.first()
但是如何在流链中实现取消/重试逻辑?或者让 ui 知道哪一步是错误的或卡住的?
解决方案
那这个呢:
suspend fun start() {
val locationResult = locateUserCase()
if(locationResult.isFailure()) {
// do location error handling
return
}
val location = locationResult.getOrThrow()
val serverResult = retrieveServerUseCase(location)
if(serverResult.isFailure()) {
// do server error handling
return
}
val server = serverResult.getOrThrow()
val configResult = retrieveConfigServerUseCase(server)
if(configResult.isFailure()) {
// do config error handling
return
}
// do total success handling
}
您允许每个案例返回一个结果,分别处理错误处理并提前返回以停止继续。显示区域之间的清晰流动,但不是回调地狱。
推荐阅读
- algorithm - 黑白滑块滤镜控制
- java - 解析JSONObject时如何制作容错代码?
- random - 在 ABAP CDS 视图中创建随机字符串
- python-3.x - 字典列表
- qt - 鼠标点击事件上的QtQuick pathCurve曲线
- android - 即使在设置了授权令牌后,也出现了来自改造的错误 401
- python - 从类方法调用实例方法,在python3中允许,在python 2中不允许?
- firebase - 在 Firebase Cloud Function 完成之前显示“加载”UI 的 UX 方法?
- php - laravel s3 在尝试屏蔽 URL 时从显示未知 SRC 的 API 获取图像
- c# - 直接在 Google-Chrome 中通过 URL 运行 WPF 应用程序