Какие сущности Android используются в Data слое Clean Architecture
Комментарии (2)
Ответ сгенерирован нейросетью и может содержать ошибки
Сущности Data слоя в Clean Architecture для Android
В Clean Architecture подходе Data слой служит мостом между доменной логикой и внешними источниками информации. Его главная цель — абстрагировать источники данных, предоставляя домену единый интерфейс для работы с информацией. Вот ключевые сущности, которые обычно используются в этом слое.
1. Репозитории (Repositories)
Это центральные компоненты Data слоя. Репозиторий реализует интерфейс, определённый в Domain слое (например, UserRepository), и инкапсулирует логику выбора источника данных (кэш, сеть, база данных). Он решает, откуда брать данные и как их кэшировать.
class UserRepositoryImpl @Inject constructor(
private val localDataSource: UserLocalDataSource,
private val remoteDataSource: UserRemoteDataSource,
private val dispatcher: CoroutineDispatcher
) : UserRepository {
override suspend fun getUser(userId: String): User {
return withContext(dispatcher) {
val localUser = localDataSource.getUser(userId)
if (localUser != null) {
return@withContext localUser
}
val remoteUser = remoteDataSource.getUser(userId)
localDataSource.saveUser(remoteUser)
remoteUser
}
}
}
2. Data Sources (Источники данных)
Они отвечают за непосредственное взаимодействие с конкретными технологиями хранения или передачи данных. Обычно разделяются на:
- Локальные источники (Local Data Sources): работают с данными на устройстве, используя Room, DataStore, SharedPreferences или файловую систему.
- Удалённые источники (Remote Data Sources): взаимодействуют с сетевыми API через ретрофит, gRPC или GraphQL.
interface UserRemoteDataSource {
suspend fun getUser(userId: String): UserDto
}
class UserRemoteDataSourceImpl @Inject constructor(
private val apiService: UserApiService
) : UserRemoteDataSource {
override suspend fun getUser(userId: String): UserDto {
return apiService.getUser(userId)
}
}
3. DTO (Data Transfer Objects) и Entity-модели
DTO используются для обмена данными с API или базой данных. Они отражают структуру внешних источников. Entity-модели (например, Room-сущности) представляют данные в локальном хранилище. Часто требуется маппинг между DTO, Entity и Domain-моделями.
@Entity(tableName = "users")
data class UserEntity(
@PrimaryKey val id: String,
val name: String,
val email: String
)
data class UserDto(
val id: String,
val username: String,
val emailAddress: String
)
// Маппинг в Domain-модель
fun UserDto.toDomain(): User {
return User(id = id, name = username, email = emailAddress)
}
4. Мапперы (Mappers)
Отвечают за преобразование данных между слоями: DTO → Domain Model, Entity → Domain Model и наоборот. Это могут быть функции-расширения или отдельные классы.
class UserMapper {
fun mapToDomain(entity: UserEntity): User {
return User(
id = entity.id,
name = entity.name,
email = entity.email
)
}
}
5. API-сервисы и DAO (Data Access Objects)
API-сервисы определяют сетевые endpoints (часто через Retrofit интерфейсы). DAO — это абстракции для доступа к базе данных в Room, содержащие методы для запросов (insert, update, delete, select).
// Сетевой сервис
interface UserApiService {
@GET("users/{id}")
suspend fun getUser(@Path("id") userId: String): UserDto
}
// DAO для Room
@Dao
interface UserDao {
@Query("SELECT * FROM users WHERE id = :userId")
suspend fun getUser(userId: String): UserEntity?
@Insert(onConflict = OnConflictStrategy.REPLACE)
suspend fun insertUser(user: UserEntity)
}
6. Базы данных и миграции
Настройка RoomDatabase включает определение entities, DAO и версий базы данных с миграциями для управления изменениями схемы.
7. Внедрение зависимостей (Dependency Injection)
Для связывания сущностей Data слоя используется DI-фреймворк (Dagger Hilt, Koin). Он управляет жизненным циклом и внедряет зависимости, такие как источники данных или репозитории, в другие слои.
@Module
@InstallIn(SingletonComponent::class)
object DataModule {
@Provides
fun provideUserRepository(
localDataSource: UserLocalDataSource,
remoteDataSource: UserRemoteDataSource
): UserRepository {
return UserRepositoryImpl(localDataSource, remoteDataSource, Dispatchers.IO)
}
}
Принципы организации Data слоя
- Инверсия зависимостей: Data слой зависит от абстракций Domain слоя (интерфейсы репозиториев), а не наоборот.
- Единый источник правды (Single Source of Truth): Репозиторий объединяет данные из разных источников, обеспечивая консистентность.
- Разделение ответственности: Каждый компонент выполняет одну чёткую задачу (сетевые запросы, кэширование, маппинг).
Правильная реализация Data слоя обеспечивает гибкость, тестируемость и надёжность приложения, позволяя легко заменять источники данных без изменения бизнес-логики.