Repository Pattern: bu nima, iOS va Android'da ma'lumotlar abstraksiyasi namunasi

Muallif: IT Sectr Nashr etilgan: 2026-02-17 O'qish vaqti: 7 daq

Repository Pattern — biznes mantiq va ma'lumot manbalari o'rtasida abstraksiya qatlamini qo'shadigan naqsh. To'g'ridan-to'g'ri API, ma'lumotlar bazasi yoki kesh chaqiruvlari o'rniga Repository ma'lumotlarni olish va saqlash uchun yagona interfeysni taqdim etadi. Bu testlash va manbalar o'rtasida almashishni soddalashtiradi. Batafsil Android Data Layer hujjatlarida.

Asosiy

  • Repository Pattern — biznes mantiq va ma'lumot manbalari (API, MB, kesh) o'rtasidagi oraliq qatlam
  • DataSource — har bir manba uchun alohida sinflar: RemoteDataSource, LocalDataSource
  • Single source of truth — Repository UI qatlami uchun yagona ma'lumot manbaiga aylanadi
  • Testlash — Repository DI orqali unit testlar uchun osongina mock-ob'ekt bilan almashtiriladi
  • Moslik — MVVM, Clean Architecture va boshqa arxitektura naqshlari bilan ishlaydi

Mobil ishlanmada Repository Pattern nima?

Repository Pattern — biznes mantiqni ma'lumot manbalariga to'g'ridan-to'g'ri kirishdan ajratib turadigan tuzilmaviy naqsh. Activity, UIViewController yoki ViewModel to'g'ridan-to'g'ri Retrofit, URLSession, Room yoki CoreData'ni chaqirish o'rniga Repository'ga murojaat qiladi. Repository ma'lumotlarni qayerdan olishni hal qiladi: tarmoqdan, ma'lumotlar bazasidan yoki keshdan va natijani yagona formatda qaytaradi. Bu yagona javobgarlik prinsipining amalga oshirilishi — UI ma'lumotlar qanday va qayerdan olinganligini bilmaydi.

Repository komponentlari interfeys (protocol), amalga oshirish va bir yoki bir nechta DataSource'ni o'z ichiga oladi. DataSource — bitta manba bilan ishlaydigan sinf: RemoteDataSource HTTP-klient orqali API'ni chaqiradi, LocalDataSource ma'lumotlar bazasiga o'qiydi va yozadi. Repository DataSource'larni konstruktor orqali qabul qiladi (Dependency Injection) va qaysi manbaga murojaat qilishni tanlaydi. Masalan, foydalanuvchilar ro'yxati so'rovida Repository avval keshni, keyin ma'lumotlar bazasini, so'ngra tarmoqni tekshiradi.

Afzalliklari Repository Pattern: ma'lumot manbalaridagi o'zgarishlar (API o'zgarishi, MB migratsiyasi) UI qatlamiga ta'sir qilmaydi; Repository yoki DataSource'ni almashtirish orqali unit testlash; UI uchun shaffof keshlash; ekran mantiqini o'zgartirmasdan online va offline rejimlari o'rtasida almashish. Android jamoasi Repository'ni Clean Architecture'da majburiy qatlam sifatida tavsiya qiladi.

iOS'da Swift bilan Repository Pattern: amalga oshirish va misol

iOS amalga oshirishi Repository Swift protokollariga asoslanadi. Repository protokoli ma'lumotlarni olish va saqlash uchun metodlarni e'lon qiladi. Haqiqiy amalga oshirish initsializator orqali kiritiladi — bu testlarda va SwiftUI preview'da amalga oshirishni almashtirishga imkon beradi. DataSource'lar ham protokollar bilan e'lon qilinadi: Protocol RemoteDataSource, Protocol LocalDataSource. ViewModel yoki Interactor aniq amalga oshirishni bilmaydi — faqat Repository protokolini biladi.

swift
protocol UserRepository {
    func getUsers() async throws -> [User]
}

protocol UserRemoteDataSource {
    func fetchUsers() async throws -> [User]
}

protocol UserLocalDataSource {
    func getCachedUsers() throws -> [User]
    func saveUsers(_: [User]) throws
}

final class UserRepositoryImpl: UserRepository {
    private let remote: UserRemoteDataSource
    private let local: UserLocalDataSource

    init(remote: UserRemoteDataSource, local: UserLocalDataSource) {
        self.remote = remote
        self.local = local
    }

    func getUsers() async throws -> [User] {
        if let cached = try? local.getCachedUsers() {
            return cached
        }
        let users = try await remote.fetchUsers()
        try local.saveUsers(users)
        return users
    }
}

Dependency Injection iOS'da Repository uchun odatda fabrika yoki DI konteyneri (Swinject, Factory) orqali sozlanadi. Testlarda UserRepository protokoli oldindan belgilangan ma'lumotlarni qaytaradigan mock amalga oshirish bilan almashtiriladi. Async-await kodni yopilishlar va delegate'larsiz sinxron va o'qilishi oson qiladi. Combine reaktivligi uchun Repository metodlari async throws o'rniga AnyPublisher qaytaradi.

Android'da Kotlin bilan Repository Pattern: Flow misoli

Android amalga oshirishi Repository asinxron ish uchun Kotlin Coroutines va Flow'dan keng foydalanadi. Google Repository'ni Android arxitekturasi bo'yicha rasmiy qo'llanmada (Android Architecture Components) tavsiya qiladi. Repository konstruktor orqali RemoteDataSource (Retrofit) va LocalDataSource (Room) ni qabul qiladi, ViewModel esa Repository'dan Flow'ga obuna bo'ladi. Repository ma'lumot strategiyasini boshqaradi: avval kesh, keyin tarmoq yoki har doim tarmoq keshga yozish bilan.

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

interface UserRemoteDataSource {
    suspend fun fetchUsers(): List<User>
}

interface UserLocalDataSource {
    fun getCachedUsers(): Flow<List<User>>
    suspend fun saveUsers(users: List<User>)
}

class UserRepositoryImpl(
    private val remote: UserRemoteDataSource,
    private val local: UserLocalDataSource
) : UserRepository {

    override fun getUsers(): Flow<Result<List<User>>> = flow {
        emit(Result.Loading)
        local.getCachedUsers().collect { cached ->
            if (cached.isNotEmpty()) {
                emit(Result.Success(cached))
            }
        }
        try {
            val users = remote.fetchUsers()
            local.saveUsers(users)
            emit(Result.Success(users))
        } catch (e: Exception) {
            emit(Result.Error(e))
        }
    }
}

Result o'rami yuqoridagi misolda Android uchun standartdir: sealed class Result ViewModel'ga yuklash holati (Loading, Success, Error) haqida xabar beradi. ViewModel collect orqali obuna bo'ladi va StateFlow yoki LiveData'ni yangilaydi. Repository Flow bilan avtomatik ravishda UI'ni ma'lumotlar bazasidagi o'zgarishlar haqida xabardor qiladi — bu UI qo'lda yangilashsiz o'zgarishlardan xabarsiz qoladigan bir martalik so'rovlardan asosiy farqdir.

DataSource: Remote, Local va ma'lumotlarni keshlash

DataSource — muayyan ma'lumot manbai bilan ishlash uchun mas'ul bo'lgan sinflar. RemoteDataSource API'dan ma'lumot olish uchun HTTP-klientdan (URLSession, Retrofit, Ktor) foydalanadi. LocalDataSource mahalliy saqlash bilan (CoreData, Realm, Room, UserDefaults, DataStore) ishlaydi. Har bir DataSource tor mas'uliyatga ega: RemoteDataSource faqat API so'rov formatini biladi, LocalDataSource — ma'lumotlar bazasi sxemasini. Repository ularni birlashtirib, keshlash strategiyasini amalga oshiradi.

DataSourceiOS PlatformasiAndroid PlatformasiManba
RemoteURLSession + CodableRetrofit + Moshi/GsonREST / GraphQL API
Local (MB)CoreData, SwiftDataRoom, SQLDelightQurilmadagi SQLite
Local (kesh)NSCache, UserDefaultsDataStore, EncryptedSPXotirada / disk
PreferensiyaUserDefaults, KeychainSharedPreferences, EncryptedSPSozlamalar, tokenlar

Keshlash strategiyalari Repository'da: Cache-First (avval kesh, keyin fon yuklash), Network-Only (faqat tarmoq, to'lov ekranlari uchun), Network-First-With-Cache-Backup (avval tarmoq, xato bo'lsa — kesh). Strategiya tanlovi ssenariyga bog'liq: mamlakatlar ro'yxatini uzoq muddat keshlash mumkin, valyuta kurslarini — 15 daqiqa, hamyon balansini — faqat tarmoqdan. Repository strategiyani amalga oshiradi va ViewModel yoki UI'ni o'zgartirmasdan uni o'zgartiradi.

Repository Pattern vs Service Layer: farqlar va tanlov

Repository va Service — bir-biriga o'xshash funksiyalarga ega turli naqshlar. Repository ma'lumotlarga kirish va ularni keshlash uchun javobgar bo'lib, ma'lumot modellarini qaytaradi. Service (yoki Interactor, Use Case) biznes mantiqni o'z ichiga oladi: validatsiya, ma'lumot transformatsiyasi, bir nechta Repository chaqiruvlarini orkestratsiya qilish. Service buyurtmani rasmiylashtirish uchun UserRepository, OrderRepository va NotificationRepository'ni birlashtirishi mumkin. Repository biznes mantiqni o'z ichiga olmaydi — faqat CRUD va keshlash.

Repository qachon tanlanadi — ko'p manbali ma'lumot navigatsiyasi (API + MB + kesh), offline-first arxitekturasi, keshlash va manbalarni shaffof almashtirish zarurati. Repository Clean Architecture'da majburiy va Google tomonidan Android ilovalari uchun tavsiya etiladi. iOS'da VIPER arxitekturasida Repository rolini Interactor qatlami bajaradi, ma'lumotlarga kirish uchun Manager yoki Service bilan o'zaro aloqada bo'ladi.

Service qachon yetarli — bitta ma'lumot manbai bilan oddiy ilovalar, yozmasdan faqat o'qish ekranlari, offline rejimi bo'lmagan loyihalar. Bunday hollarda DataSource to'g'ridan-to'g'ri ViewModel yoki Presenter tomonidan ishlatiladi, Repository esa ortiqcha qatlamga aylanadi. Biroq, Repository'ni erta bosqichda qo'shish katta xarajat talab qilmaydi va kelajakda keshlash va testlarni qo'shishni osonlashtiradi.

Tez-tez beriladigan savollar

Repository DataSource'dan qanday farq qiladi?

DataSource — bitta manba bilan ishlaydigan sinf (API, MB, kesh). Repository — bir nechta DataSource'ni boshqaradigan va yagona interfeys taqdim etadigan sinf. Repository qaysi DataSource'dan ma'lumot olishni hal qiladi va keshlashni muvofiqlashtiradi. DataSource boshqa manbalarning mavjudligini bilmaydi, Repository har bir manbaning amalga oshirish tafsilotlarini bilmaydi.

iOS SwiftUI'da Repository kerakmi?

Ha, Repository SwiftUI'da ma'lumotlarni View'dan ajratish uchun foydalidir. ViewModel Repository'dan Publisher'ga obuna bo'ladi, Repository esa keshlash va sinxronizatsiyani boshqaradi. Oddiy ilovalarda to'g'ridan-to'g'ri ViewModel'da URLSession ishlatish mumkin, ammo testlash va masshtablash uchun Repository afzalroq. Apple bu naqshni majburlamaydi, lekin u SwiftData va Network.framework bilan mos keladi.

Bir nechta DataSource bilan Repository qanday testlanadi?

DataSource'lar Dependency Injection orqali mock-ob'ektlar bilan almashtiriladi. Test mock RemoteDataSource (oldindan belgilangan JSON qaytaradi) va mock LocalDataSource (ma'lumotlar saqlanganligini tekshiradi) yaratadi. Repository alohida testlanadi: keshlash strategiyasi, xato boshqaruvi va chaqiruvlarning to'g'ri tartibi tekshiriladi. Integratsiya testlari uchun TestDispatcher (Kotlin) yoki MainActor.run (Swift) ishlatiladi.

Repository interfeyssiz (protocol) ishlatilishi mumkinmi?

Mumkin, lekin tavsiya etilmaydi. Protokolsiz testlarda va preview'da amalga oshirishni almashtirish mumkin emas. Kotlin'da Repository interfeysi DI (Dagger, Hilt, Koin) orqali amalga oshirishni almashtirishga imkon beradi. Swift'da Repository protokoli async-await va Combine kodini testlash uchun majburiydir. Istisno — keshlash mantiqiga ega bo'lmagan, bitta ma'lumot manbai bilan oddiy loyihalar.

Repository kontekstida offline-first nima?

Offline-first — ilova internet bo'lmagan holda mahalliy ma'lumotlardan foydalanib ishlaydigan strategiya. Repository asosiy rol o'ynaydi: avval mahalliy DataSource'dan ma'lumotlarni qaytaradi, keyin fonda server bilan sinxronlashadi. Foydalanuvchi ma'lumotlarni darhol ko'radi, Repository esa tarmoqdan yuklagandan keyin ularni yangilaydi. Room Flow bilan mahalliy ma'lumotlar bazasida o'zgarishlar bo'lganda UI'ni reaktiv yangilashni ta'minlaydi.

Xulosa

  • Repository Pattern — UI va ma'lumot manbalari o'rtasidagi abstraksiya qatlami
  • DataSource — API, MB va kesh uchun alohida sinflar
  • Protokollar — testlash va amalga oshirishlarni almashtirish uchun majburiy
  • Keshlash strategiyalari — Cache-First, Network-Only, Network-First-With-Cache-Backup
  • iOS — protokollar bilan async-await yoki Combine
  • Android — Kotlin Flow + Room + Retrofit, Google tomonidan tavsiya etilgan yondashuv
  • Testlash — DI orqali mock DataSource, keshlash strategiyalarini tekshirish

Biz kalit topshirig'i bilan mobil ilovani ishlab chiqamiz

IT Sectr 2017-yildan beri startaplar va korxonalar uchun iOS va Android ilovalarini yaratadi. Biz sizga maslahat beramiz va eng yaxshi yechimni taklif qilamiz.

Loyihani muhokama qilish

Shuningdek o'qing