Singleton — bu nima, iOS va Android-da sinfning yagona namunasi

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

Singleton (yakka) — sinfning yagona namunasini kafolatlaydigan va unga global kirish nuqtasini taqdim etadigan yaratuvchi naqsh. Singleton mobil ishlanmada umumiy resurslar uchun keng qoʻllanadi: tarmoq mijozlari, maʼlumotlar bazalari, sozlamalar menejerlari. Naqsh klassik GoF (1994) kitobida tasvirlangan va eng taniqlilardan biri boʻlib qolmoqda. Batafsil — Refactoring Guru: Singleton.

Asosiy

  • Singleton — butun ilova uchun sinfning bitta namunasini kafolatlaydi
  • Global kirish nuqtasi — shared statik xususiyati yoki companion object
  • Thread safety — koʻp tarmoqli muhitda toʻgʻri ishlash uchun sinxronizatsiya talab qilinadi
  • Tanqid — Singleton testlashni qiyinlashtiradi va yashirin bogʻliqliklarni yaratadi
  • Alternativlar — Dependency Injection, Service Locator Singleton oʻrnini bosish uchun

Singleton nima: yakka naqshning mohiyati?

Singleton (yakka) — 1994 yilda GoF (Gang of Four) tomonidan tasvirlangan yaratuvchi dizayn naqshi. Naqsh ikkita vazifani hal qiladi: sinf namunasini yaratishni bitta obʼyekt bilan cheklaydi va ushbu obʼyektga global kirishni taʼminlaydi. Singleton noyob boʻlishi kerak boʻlgan resurslar uchun foydalidir: sessiya fabrikasi, tasvir keshi, maʼlumotlar bazasiga ulanish menejeri, Crashlytics yoki Analytics mijozi.

Singleton implementatsiyasi xususiy konstruktor (tashqi yaratishni taqiqlaydi), yagona namuna bilan statik maydon va statik kirish metodi (shared, instance, getInstance) talab qiladi. Mijozlar obʼyekt yaratish haqida qaygʻurmasdan Singleton.shared.method() chaqiradi. Naqsh iOS va Android da mashhur: URLSession.shared, UserDefaults.standard, FirebaseApp.sharedInstance — bularning barchasi Singleton. Biroq Singleton dan haddan tashqari foydalanish Global State anti-naqshiga olib keladi.

Singleton muammolari — yashirin bogʻliqliklar (sinflar Singleton obʼyektiga bilvosita bogʻliq), testlash qiyinligi (qoʻshimcha harakatsiz testda namunani almashtirib boʻlmaydi), Single Responsibility Principle ni buzish (Singleton ham oʻz namunasini, ham biznes mantigʻini boshqaradi). Zamonaviy mobil ishlanma yagona namunalarni boshqarish uchun DI (Dagger, Hilt, Swinject) ni afzal koʻradi — DI konteyneri obʼyektni bir marta yaratadi va uni konstruktor orqali kiritadi.

iOS da Swift da Singleton: shared va statik xususiyatlar

Swift Singleton xususiy boshlovchi bilan shared statik xususiyati orqali implementatsiya qilinadi. Swift 3 dan boshlab, statik xususiyatlarning kech boshlanishi kafolatlangan holda ip xavfsiz — kompilyator dispatch_once orqali avtomatik sinxronizatsiya qoʻshadi. static let shared = Class() eʼlon qilish va init() ni xususiy qilish kifoya. Swift boshlashdan keyin bir ipli kirish uchun qoʻshimcha sinxronizatsiya talab qilmaydi.

swift
final class NetworkManager {
    // Thread-safe Singleton
    static let shared = NetworkManager()

    private init() {
        URLSessionConfiguration.default.timeoutIntervalForRequest = 30
    }

    private var cache = NSCache<NSString, NSData>()

    func fetchData(from url: URL) async throws -> Data {
        let key = url.absoluteString as NSString
        if let cached = cache.object(forKey: key) {
            return cached as Data
        }
        let (data, _) = try await URLSession.shared.data(from: url)
        cache.setObject(data as NSData, forKey: key)
        return data
    }
}

// Foydalanish
let data = try await NetworkManager.shared.fetchData(from: url)

Apple Singleton — iOS SDK da koʻplab obʼyektlar Singleton dan foydalanadi: UIApplication.shared, UIScreen.main, FileManager.default, NotificationCenter.default, UserDefaults.standard. Apple jismoniy jihatdan noyob boʻlgan xizmatlar (bitta ekran, bitta ilova) uchun Singleton dan foydalanadi. Dasturchilar bu naqshni oʻz xizmatlari uchun koʻchiradilar. SwiftUI da Singleton ga global kirish Environment va @EnvironmentObject bilan almashtiriladi, bu test qilish imkoniyatini yaxshilaydi.

Android da Kotlin da Singleton: companion object va object

Kotlin Singleton — eng oddiy usul: object kalit soʻzi birinchi kirishda kech boshlash bilan sinf-singletonni eʼlon qiladi. Kotlin object ip xavfsiz va qoʻshimcha sinxronizatsiya talab qilmaydi. Agar konstruktor parametrlari bilan Singleton kerak boʻlsa, lazy-delegat bilan companion object ishlatiladi. Android da Singleton koʻpincha Application konteksti va Application.onCreate() orqali boshlanadigan xizmatlar uchun zarur.

kotlin
// Variant 1: object — parametrsiz oddiy Singleton
object AppPreferences {
    private val prefs = Application.instance
        .getSharedPreferences("app", Context.MODE_PRIVATE)

    var isFirstLaunch: Boolean
        get() = prefs.getBoolean("first_launch", true)
        set(value) = prefs.edit { putBoolean("first_launch", value) }
}

// Variant 2: companion object — parametrlar bilan Singleton
class ApiClient private constructor(baseUrl: String) {
    companion object {
        @Volatile
        private var instance: ApiClient? = null

        fun getInstance(baseUrl: String): ApiClient {
            return instance ?: this.synchronized {
                instance ?: ApiClient(baseUrl).also { instance = it }
            }
        }
    }

    fun request(endpoint: String): String { /* ... */ }
}

Android SDK Singleton — Android ning koʻplab tizim xizmatlari Singleton ni implementatsiya qiladi: context.getSystemService(), Room.databaseBuilder(), Retrofit.Builder(). Misollar SharedPreferences, MediaPlayer, AudioManager ni oʻz ichiga oladi. Android ilovalarida Singleton koʻpincha repository, menejer va fabrikalar uchun ishlatiladi. Google Singleton ni DI (Hilt, Koin) bilan almashtirishni tavsiya qiladi, bu yerda Singleton doirasi (Scope.Singleton yoki @Singleton) konteyner tomonidan boshqariladi va sinf test qilinadigan boʻlib qoladi.

Thread safety: dispatch_once, synchronized va lock

Thread safety — koʻp tarmoqli muhitda Singleton uchun muhim talab. Sinxronizatsiyasiz ikkita ip bir vaqtda instance == null ni tekshirib, ikkita namuna yaratishi mumkin. Yechim — birinchi yaratishda bloklash va boshlashdan keyin boʻshatish. Swift da statik xususiyatlar (static let) sukut boʻyicha ip xavfsiz. Kotlin da object ip xavfsiz. Kotlin da Java uslubi uchun synchronized yoki @Volatile + double-check locking ishlatiladi.

TilMexanizmIp xavfsizligiKech boshlash
Swiftstatic letdispatch_once (avto)Ha, birinchi kirishda
Kotlin objectObject declarationSinf boshlovchisi ip xavfsizHa, birinchi kirishda
Kotlin companionsynchronized + @VolatileDouble-checked lockingHa, lazy yoki synchronized orqali
Javasynchronized + volatileDouble-checked lockingHa, getInstance() da

Double-checked locking — Singleton ni kech boshlash uchun naqsh. Birinchi tekshirish sinxronizatsiyasiz (namuna allaqachon yaratilgan boʻlsa tez), ikkinchisi — synchronized ichida (faqat bitta ip tomonidan yaratish). @Volatile barcha iplar uchun oʻzgarishlarning koʻrinishini kafolatlaydi. Volatile boʻlmasa, boshqa ip qisman yaratilgan obʼyektni koʻrishi mumkin. Kotlin da LazyThreadSafetyMode.SYNCHRONIZED bilan lazy-delegat avtomatik ravishda double-checked locking ni implementatsiya qiladi.

Singleton vs Dependency Injection: qachon ishlatish

Dependency Injection — yagona namunani boshqarish uchun Singleton ga alternativa. DI konteyneri (Dagger, Hilt, Koin, Swinject) obʼyektni Singleton doirasida bir marta yaratadi va uni konstruktor orqali kiritadi. Sinf oʻz Singleton statusi haqida bilmaydi — bu konteyner tomonidan hal qilinadi. Kod test qilinadigan boʻladi: testda DI moduli mock moduli bilan almashtiriladi. DI ning afzalliklari: konstruktorda aniq bogʻliqliklar, bekor qilish imkoniyati, yagona hayot aylanishi.

Singleton qachon oqlanadi — tizim darajasidagi obʼyektlar: Crashlytics, Analytics, Logging. Bu xizmatlar AppDelegate/Application da bir marta boshlanadi va hamma joyda ishlatiladi. DI ular uchun ortiqcha. Singleton shuningdek tasvir keshlari (NSCache, Coil, Glide) uchun qulay, bu yerda global kirish ishlash bilan oqlanadi. Qolgan hamma narsa uchun DI afzal: bogʻliqliklarni koʻrinadigan qiladi, testlash va qayta qurishni soddalashtiradi.

Gibrid yondashuv — testlar uchun bekor qilish imkoniyati bilan Singleton. Swift da protokol + statik xususiyat ishlatiladi, test uni almashtirishi mumkin (masalan, URLSession uchun URLProtocol orqali). Kotlin da — refleksiya yoki setter orqali test mock oʻrnatadigan injectable xususiyati bilan open class. Bu yondashuv Singleton ning soddaligini saqlaydi, lekin testlash uchun vositalar beradi. Google Android uchun Hilt ni tavsiya qiladi, Apple iOS uchun DI ni talab qilmaydi — tanlov jamoaga bogʻliq.

Tez-tez soʻraladigan savollar

Singleton — bu anti-naqshmi?

Yoʻq, Singleton GoF naqshi, lekin uning tez-tez notoʻgʻri ishlatilishi uni Global State anti-naqshiga aylantiradi. Singleton jismoniy jihatdan noyob resurslar (ekran, printer, fayl tizimi) uchun oqlanadi. Muammolar Singleton maʼlumotlarni boshqarish uchun ishlatilganda paydo boʻladi: yashirin bogʻliqliklar, testlash qiyinligi, Single Responsibility Principle ni buzish. Zamonaviy alternativa — Singleton doirasi bilan DI.

Singleton ishlatadigan kodni qanday testlash kerak?

Uch yondashuv: (1) protokol orqali — Singleton protokolni implementatsiya qiladi, testlar implementatsiyani almashtiradi; (2) DI orqali — Singleton konstruktor orqali bogʻliqlik sifatida kiritiladi; (3) reset-metod orqali — Singleton testlarda holatni tiklash uchun metodga ega (faqat test buildi uchun). Birinchi yondashuv afzal, uchinchisi — ishlab chiqarish uchun xavfli. Swift testlarda runtime manipulyatsiyalari orqali shared xususiyatini almashtirishga imkon beradi.

Kotlin object Java Singleton dan nimasi bilan farq qiladi?

Kotlin object — bayt kod darajasida Singleton yaratadigan til konstruksiyasi. Java implementatsiyasidan farqli oʻlaroq xususiy konstruktor va getInstance() bilan, object ip xavfsizligi, kech boshlash va meros olishni taqiqlashni kafolatlaydi. Java Singleton koʻp tarmoqli muhitda toʻgʻri ishlash uchun qoʻlda sinxronizatsiya (synchronized) va volatile talab qiladi. Kotlin object — Android da eng xavfsiz va ixcham usul.

Singleton ni meros qilib olish mumkinmi?

Singleton ni meros qilib olish naqshni buzadi: agar Singleton sinfi meros qilib olinishi mumkin boʻlsa, pastki sinf ikkinchi namunani yaratishi mumkin, noyoblikni buzib. Swift da final class meros olishni taqiqlaydi. Kotlin object meros qilib olinmaydi (object — sealed). Agar variantli Singleton kerak boʻlsa, Singleton doirasi bilan DI konteyneridan foydalaning: bitta namunani kafolatlaydi va interfeyslar orqali meros olishni qoʻllab-quvvatlaydi.

Android da Singleton ga parametrlarni qanday uzatish kerak?

Parametrlar init(context: Application) yoki getInstance(param) orqali uzatiladi. Kotlin object parametr qabul qilmaydi — fabrika metodi getInstance(param) bilan companion object dan foydalaning. Hilt muammoni hal qiladi: @Singleton + @Inject constructor(context: Application) — DI konteyneri Application kontekstini avtomatik kiritadi. Retrofit mijozi uchun parametrlar (baseUrl, interceptors) DI modulida builder orqali uzatiladi.

Xulosa

  • Singleton — yagona namuna va global kirish bilan naqsh
  • Swift shared — kompilyatordan ip xavfsizligi bilan static let
  • Kotlin object — qoʻshimcha kodsiz kech boshlash
  • Thread safety — Java uchun double-checked locking, Swift/Kotlin uchun avtomatik
  • Apple SDK — UIApplication.shared, UserDefaults.standard, FileManager.default
  • Android SDK — Retrofit, Room, SharedPreferences Singleton menejerlari orqali
  • Alternativlar — test qilinadigan kod uchun Dependency Injection

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