引用规则:
源代码依赖关系只能指向内部。
我猜这取决于架构。让我以一个例子来解释一下:
架构:
DOMAIN <- DATA <- PRESENTATION
位置:
DATA -> LOCAL
|
v
REMOTE
注意: DOMAIN 代表最内层的圆圈,PRESENTATION 代表最外层的圆圈。
现在 DOMAIN 是一个纯 Kotlin 模块,没有任何 Android 依赖。让我们定义一个仓库:
interface ProfileRepository {
fun getProfile(): Profile?
fun updateProfile(profile: Profile): Profile
}
我们将其实现在数据层中(这是一个Android库):
class ProfileRepositoryImpl(
private val networkManager: NetworkManager,
private val remoteDataSource: ProfileRemoteDataSource,
private val localDataSource: ProfileLocalDataSource
): ProfileRepository {
override fun getProfile(): Profile? {
return if(networkManager.isNetworkAvailable) {
localDataSource.insert(remoteDataSource.get())
} else {
localDataSource.get()
}
}
override fun updateProfile(profile: Profile): Profile {
val updatedProfile = remoteDataSource.update(profile)
return localDataSource.insert(updatedProfile)
}
}
class ProfileRemoteDataSource(
private val api: ProfileApi,
private val mapper: Mapper<ProfileDto, Profile>
) {
fun get(): Profile {
return mapper.toModel(api.getProfile())
}
fun update(profile: Profile): Profile {
val dto = api.updateProfile(
mapper.fromModel(profile)
)
return mapper.toModel(dto)
}
}
class ProfileLocalDataSource(
private val dao: ProfileDao,
private val mapper: Mapper<ProfileEntity, Profile>
) {
fun insert(profile: Profile): Profile {
dao.insert(mapper.fromModel(profile))
return requireNotNull(get())
}
fun get(): Profile? {
return dao.get()?.let(mapper::toModel)
}
}
interface Mapper<T : Any, Model : Any> {
fun toModel(value: T): Model
fun fromModel(value: Model): T
}
LOCAL
模块是一个 Android 库,独立于任何依赖项,并公开 DAO
和 Entity
对象:
interface ProfileDao {
fun insert(profile: ProfileEntity)
fun get(): ProfileEntity?
}
同样地,对于REMOTE
模块:
interface ProfileApi {
fun get(): ProfileDto
fun update(profile: ProfileDto): ProfileDto
}
因此,对我来说,让Source
类返回DTO
和Entity
对象就没有意义。仓库类将看起来像这样:
class ProfileRepositoryImpl(
private val networkManager: NetworkManager,
private val remoteDataSource: ProfileRemoteDataSource,
private val remoteDataMapper: Mapper<ProfileDto, Profile>,
private val localDataSource: ProfileLocalDataSource,
private val localDataMapper: Mapper<ProfileEntity, Profile>
) : ProfileRepository {
override fun getProfile(): Profile? {
if (networkManager.isNetworkAvailable) {
val dto = remoteDataSource.get()
val profile = remoteDataMapper.toModel(dto)
val entity = localDataMapper.fromModel(profile)
localDataSource.insert(entity)
}
return localDataSource.get()?.let(localDataMapper::toModel)
}
override fun updateProfile(profile: Profile): Profile {
val request = remoteDataMapper.fromModel(profile)
val dto = remoteDataSource.update(request)
val updatedProfile = remoteDataMapper.toModel(dto)
val entity = localDataMapper.fromModel(updatedProfile)
localDataSource.insert(entity)
return localDataMapper.toModel(
requireNotNull(localDataSource.get())
)
}
}
在你的例子中,你只考虑了
GET
操作。在这里,对于
UPDATE
操作,我们还需要映射
DOMAIN
对象。因此,如果在Repo类中进行对象映射,随着我们添加更多的功能,Repo类会变得非常混乱。
我认为这将取决于系统的整体架构。