【问题标题】:How to perform a request chains in clean architecture?如何在干净的架构中执行请求链?
【发布时间】:2021-09-28 13:44:11
【问题描述】:

在我们的例子中,我需要在应用程序启动时执行请求链,例如

  1. 应用程序需要通过 gis 或 IP 地址检索位置
  2. 通过 http 按位置请求服务器列表
  3. 从我们获得的服务器列表中的服务器请求远程配置

我为每个项目创建一个数据层

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...
         }
       }
     }
   }
}

我觉得太丑了

我可以通过 hilt 注入来做到这一点,存储库返回一个 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 知道哪一步出错或卡住了?

【问题讨论】:

    标签: android kotlin clean-architecture


    【解决方案1】:

    这个呢:

    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 
    }
    

    您允许每个案例返回一个结果,分别处理错误处理并提前返回以停止继续。 显示区域之间的清晰流动,但不是回调地狱。

    【讨论】:

      猜你喜欢
      • 2022-01-05
      • 2021-08-13
      • 1970-01-01
      • 2018-10-09
      • 2017-08-24
      • 2019-03-28
      • 1970-01-01
      • 2021-12-22
      • 2020-03-10
      相关资源
      最近更新 更多