You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Clean架构MVVM中API响应处理:DTO与实体映射问题求助

问题描述

基于Clean Architecture构建的应用中,Network Layer的handleApiResponse泛型方法返回NetworkResponse<JokeResponseDto>,但JokeRepositoryImpl的getJoke方法需要返回NetworkResponse<JokeResponse>,缺少DTO到实体的映射逻辑,且泛型方法中难以直接加入映射。已有JokeResponseMapper实现了Mapper<JokeResponseDto, JokeResponse>接口。

方案一:修改handleApiResponse支持映射重载

新增带映射器参数的重载方法,在成功响应时自动完成DTO到实体的转换:

1. 新增重载的handleApiResponse函数

suspend fun <F, T> handleApiResponse(
    execute: suspend () -> Response<F>,
    mapper: Mapper<F, T>
): NetworkResponse<T> {
    return try {
        val response = execute()
        val body = response.body()
        if (response.isSuccessful && body != null) {
            NetworkResponse.Success(data = mapper.mapFrom(body))
        } else {
            NetworkResponse.Error(errorMessage = response.message())
        }
    } catch (exception: HttpException) {
        NetworkResponse.Error(errorMessage = exception.localizedMessage)
    } catch (throwable: Throwable) {
        NetworkResponse.Exception(throwable = throwable)
    }
}

2. 修改JokeRepositoryImpl注入映射器并调用

class JokeRepositoryImpl @Inject constructor(
    private val jokeApi: JokeApi,
    private val jokeResponseMapper: JokeResponseMapper
) : JokeRepository {
    override suspend fun getJoke(): NetworkResponse<JokeResponse> {
        return handleApiResponse(
            execute = { jokeApi.getJoke() },
            mapper = jokeResponseMapper
        )
    }
}

方案二:在Repository层手动处理映射

若不想修改原有handleApiResponse逻辑,可在Repository中手动转换响应:

class JokeRepositoryImpl @Inject constructor(
    private val jokeApi: JokeApi,
    private val jokeResponseMapper: JokeResponseMapper
) : JokeRepository {
    override suspend fun getJoke(): NetworkResponse<JokeResponse> {
        val dtoResponse = handleApiResponse { jokeApi.getJoke() }
        return when (dtoResponse) {
            is NetworkResponse.Success -> {
                NetworkResponse.Success(jokeResponseMapper.mapFrom(dtoResponse.data))
            }
            is NetworkResponse.Error -> {
                NetworkResponse.Error(dtoResponse.errorMessage)
            }
            is NetworkResponse.Exception -> {
                NetworkResponse.Exception(dtoResponse.exception!!)
            }
        }
    }
}

补充说明

  • 方案一通用性强,适合多Repository复用映射逻辑;方案二更灵活,可在Repository中添加额外业务处理。
  • 需确保JokeResponseMapper已通过DI框架(如Hilt)完成注入,保证依赖解耦。

内容的提问来源于stack exchange,提问作者Swapnil Musale

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.12 15:26:18