← Назад к вопросам

Приведи пример абстракции

1.0 Junior🔥 61 комментариев
#Архитектура и паттерны

Комментарии (1)

🐱
deepseek-v3.2PrepBro AI6 апр. 2026 г.(ред.)

Ответ сгенерирован нейросетью и может содержать ошибки

Пример абстракции в программировании на Kotlin для Android

Абстракция — это один из ключевых принципов объектно-ориентированного программирования (ООП), который позволяет скрывать сложную реализацию и показывать только необходимые детали пользователю. В Android-разработке абстракция применяется повсеместно, например, при работе с API, базами данных или UI-компонентами. Рассмотрим практический пример на Kotlin.

Задача: Управление сетевыми запросами

Допустим, нам нужно выполнять сетевые запросы в приложении. Прямая работа с HttpURLConnection или Retrofit на низком уровне может быть громоздкой. Мы создадим абстракцию, чтобы упростить этот процесс.

Реализация абстракции

Сначала определим интерфейс NetworkService, который описывает контракт для сетевых операций:

interface NetworkService {
    suspend fun fetchUsers(): List<User>
    suspend fun fetchPosts(userId: String): List<Post>
}

Здесь интерфейс абстрагирует конкретные детали реализации — он только говорит, что должно быть сделано, но не как.

Затем создадим конкретную реализацию с использованием библиотеки Retrofit:

class RetrofitNetworkService(private val api: Api) : NetworkService {
    override suspend fun fetchUsers(): List<User> {
        return api.getUsers()
    }
    
    override suspend fun fetchPosts(userId: String): List<Post> {
        return api.getPosts(userId)
    }
}

RetrofitNetworkService скрывает детали: настройку Retrofit, обработку ошибок, преобразование JSON. Для остального кода это просто источник данных.

Использование абстракции

В ViewModel или UseCase мы работаем только с интерфейсом:

class UserViewModel(private val networkService: NetworkService) : ViewModel() {
    private val _users = MutableLiveData<List<User>>()
    val users: LiveData<List<User>> = _users
    
    fun loadUsers() {
        viewModelScope.launch {
            try {
                _users.value = networkService.fetchUsers()
            } catch (e: Exception) {
                // Обработка ошибок
            }
        }
    }
}

Преимущества такой абстракции:

  • Сокрытие сложности: Коду UserViewModel не нужно знать о деталях сетевого слоя.
  • Гибкость: Мы можем легко заменить Retrofit на Ktor или мок-реализацию для тестирования.
  • Упрощение тестирования: В инструментальных тестах мы подменяем NetworkService на фейковый объект.
  • Соблюдение принципа единственной ответственности: Каждый класс отвечает за свою часть логики.

Расширенный пример: Repository pattern

В Android часто используют паттерн Repository, который дополнительно абстрагирует источник данных:

interface UserRepository {
    suspend fun getUsers(): Result<List<User>>
}

class UserRepositoryImpl(
    private val networkService: NetworkService,
    private val localDataSource: LocalDataSource
) : UserRepository {
    override suspend fun getUsers(): Result<List<User>> {
        return try {
            val remoteUsers = networkService.fetchUsers()
            localDataSource.saveUsers(remoteUsers)
            Result.success(remoteUsers)
        } catch (e: Exception) {
            Result.failure(e)
        }
    }
}

Здесь UserRepository абстрагирует ещё выше — вызывающая сторона даже не знает, откуда приходят данные (сеть, база данных или кэш).

Заключение: Абстракция в Android позволяет создавать гибкую, поддерживаемую и тестируемую архитектуру приложения, уменьшая связность компонентов и скрывая ненужные детали реализации. Это особенно важно в долгосрочной перспективе при масштабировании проектов.

Приведи пример абстракции | PrepBro