Observer — a változásokra való előfizetési minta kulcsfogalmai

Szerző: IT Sectr Megjelenés: 2026-02-17 Olvasási idő: 7 perc

Observer — egy viselkedési minta, amelyben egy objektum (kiadó) értesíti a számos előfizetőt az állapotváltozásairól. A mobil fejlesztésben az Observer a reaktív mechanikák alapját képezi: az UI előfizet az adatváltozásokra és automatikusan frissül. A minta a NotificationCenter-ben iOS-en és a LiveData/Flow-ban Android-on van implementálva. Bővebben — a Refactoring Guru: Observer oldalon.

Főbb pontok

  • Observer — előfizetési minta: egy kiadó, számos előfizető
  • NotificationCenter — az Observer beépített implementációja iOS/macOS rendszeren
  • Flow és LiveData — az Observer reaktív implementációi Android-ban
  • Push vs Pull — a kiadó küldhet adatokat vagy értesíthet eseményekről
  • Memóriaszivárgás — az előfizetőknek le kell iratkozniuk a szivárgások megelőzése érdekében

Mi az Observer: a megfigyelő minta lényege?

Observer (megfigyelő) — egy GoF viselkedési minta, amely «egy-többöz» függőséget határoz meg objektumok között. Amikor egy objektum (Subject vagy Observable) megváltoztatja az állapotát, az összes függő objektum (Observers) automatikusan értesül és frissül. A minta gyenge csatolást valósít meg: a kiadó nem ismeri az előfizetők konkrét osztályait — csak azt, hogy implementálják az Observer interfászt.

Observer struktúra magában foglalja a Subject interfászt az attach(), detach(), notify() metódusokkal és az Observer interfászt az update() metódussal. A ConcreteSubject tárolja az állapotot és az előfizetők listáját. A ConcreteObserver implementálja az update()-et és reagál a változásokra. A mobil fejlesztésben a klasszikus GoF implementáció ritkán fordul elő — beépített mechanizmusok váltják fel: NotificationCenter, Combine, Flow, LiveData, amelyek ugyanazt az ötletet valósítják meg modern API-val.

Push vs Pull modell — a Push modellben a Subject adatokat küld az összes előfizetőnek (NotificationCenter.post). A Pull modellben a Subject csak értesít, és az előfizető maga kéri le az adatokat. Az Android LiveData Push-t használ (az adatok az observe()-ban kerülnek átadásra), az RxJava/Flow mindkét modellt támogatja. A választás a feladattól függ: a Push egyszerűbb az UI-frissítésekhez, a Pull hatékonyabb nagy adatmennyiségek esetén, amelyeket az előfizető esetleg nem akar megkapni.

Observer iOS-ben: NotificationCenter, Combine és KVO

NotificationCenter — az Observer implementálására szolgáló beépített iOS/macOS mechanizmus. A kiadó Notification-t küld a NotificationCenter.default.post(name:, object:, userInfo:) segítségével. Az előfizető az addObserver(forName:, queue:, using:) segítségével regisztrál. A NotificationCenter támogatja a névvel ellátott értesítéseket (Notification.Name) és bármilyen adatot átadhat a userInfo-ban. UIKeyboardWillShowNotification, UIApplicationDidEnterBackgroundNotification — rendszerpéldák.

swift
extension Notification.Name {
    static let userDidLogin = Notification.Name("userDidLogin")
}

// Kiadó
NotificationCenter.default.post(
    name: .userDidLogin,
    object: nil,
    userInfo: ["userId": "123"]
)

// Előfizető
class ProfileViewModel {
    private var observers: [NSObjectProtocol] = []

    func startObserving() {
        let observer = NotificationCenter.default.addObserver(
            forName: .userDidLogin,
            object: nil,
            queue: .main
        ) { [weak self] notification in
            guard let userId = notification.userInfo?["userId"] as? String else { return }
            // Az előfizető reagál az eseményre
            self?.loadProfile(userId: userId)
        }
        observers.append(observer)
    }

    func stopObserving() {
        observers.forEach { NotificationCenter.default.removeObserver($0) }
        observers.removeAll()
    }
}

Combine framework — egy modern reaktív alternatíva a NotificationCenter számára, iOS 13-tól elérhető. Publisher (NotificationCenter, URLSession.Timer) — kiadó, Subscriber (sink, assign) — előfizető. A Combine operátorokat (map, filter, combineLatest) ad hozzá az adatfolyam transzformálásához. @Published — property wrapper, amely automatikusan értesíti az előfizetőket a változásokról. Az MVVM-ben SwiftUI-val a Combine helyettesíti a NotificationCenter-t a ViewModel és View összekapcsolásához.

KVO (Key-Value Observing) — egy régi ObjC/Swift mechanizmus objektumok egyedi tulajdonságainak megfigyelésére. @objc dynamic var name: String — megfigyelt tulajdonság. observe(.name) — előfizetés. A KVO csak @objc-kompatibilis osztályokkal és ObjC öröklődéssel működik. Az Apple a KVO helyett a Combine és @Published használatát ajánlja új projektekben. A KVO továbbra is releváns a UIKit kompatibilitás miatt hibrid projektekben.

Observer Android-ban: LiveData, StateFlow és SharedFlow

LiveData — az Observer implementálására szolgáló Android Architecture Components komponens. Egy Observable osztály, amely értesíti az előfizetőket az adatváltozásokról. A LiveData figyelembe veszi az életciklust: az előfizetők (LifecycleOwner) automatikusan leiratkoznak a megsemmisüléskor. A LiveData Push modell: az adatok az observe()-ban kerülnek átadásra. A LiveData az MVVM alapvető építőeleme Android-ban a Jetpack Compose bevezetése előtt.

kotlin
// ViewModel — kiadó
class UserViewModel : ViewModel() {
    private val _user = MutableLiveData<User?>(null)
    val user: LiveData<User?> = _user

    fun loadUser(id: String) {
        viewModelScope.launch {
            val result = userRepository.getUser(id)
            _user.value = result
        }
    }
}

// Fragment — előfizető
class UserFragment : Fragment() {
    private val viewModel: UserViewModel by viewModels()

    override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
        viewModel.user.observe(viewLifecycleOwner) { user ->
            // Az előfizető reagál a változásokra
            userName.text = user?.name
            userEmail.text = user?.email
        }
    }
}

StateFlow és SharedFlow — reaktív típusok a Kotlin Coroutines-ból, amelyek felváltották a LiveData-t a Jetpack Compose-ban. StateFlow — megfigyelhető állapottartó (state holder) rögzített aktuális értékkel. SharedFlow — konfigurálható hot flow állapot nélkül, alkalmas egyszeri eseményekre (navigáció, toastok). Mindkét típus szorosan integrálódik a Compose-szal: collectAsState(), collectAsEffect(). A StateFlow kötelező a modern Android projektekben Compose-szal.

LiveData vs StateFlow — a LiveData az Android Lifecycle-hez kötött, a StateFlow platformfüggetlen. A StateFlow támogatja a coroutines-t, operátorokat (map, filter) és Android függőségek nélkül tesztelhető. A LiveData egyszerűbb a Java kompatibilitás szempontjából. A Google a StateFlow-t ajánlja új, Kotlin + Compose projektekhez, a LiveData-t — régi projektek vagy Java kód támogatására.

Előfizetések kezelése és memóriaszivárgás

Memóriaszivárgás (memory leaks) — az Observer fő problémája a megfelelő előfizetéskezelés nélkül. Ha egy előfizető (Activity, Fragment, UIViewController) megsemmisült, de nem iratkozott le, a kiadó továbbra is tartja a referenciát, és a garbage collector nem tudja felszabadítani a memóriát. Android-ban a LifecycleOwner-nek (Activity/Fragment) meg kell hívnia a removeObserver()-t, vagy használnia kell az observe(viewLifecycleOwner)-t. iOS-ben — removeObserver a deinit-ben vagy disposeBag a Combine-ban.

PlatformObserver mechanizmusAutomatikus leiratkozásKézi leiratkozás
iOSNotificationCenterNemremoveObserver() a deinit-ben
iOSCombine (sink)Nemstore(in: &bag) — DisposeBag
iOSKVONemremoveObserver() a deinit-ben
AndroidLiveDataIgen (LifecycleOwner)removeObserver() opcionális
AndroidStateFlowviewModelScope-on keresztülcancel() Job leiratkozáskor
AndroidRxJavaNemdispose() a CompositeDisposable-ban

Gyenge referencia (weak reference) az előfizetőkben — az előfizetési blokkban használjon [weak self]-et Swift-ben és hivatkozzon lifecycle scope-ra Kotlin-ban. A LiveData automatikusan kezeli az előfizetést a LifecycleOwner segítségével — az előfizetés csak akkor aktív, amikor a Lifecycle STARTED vagy RESUMED állapotban van. A StateFlow a Compose-ban a collectAsState()-t használja a lifecycle figyelembevételével. A NotificationCenter iOS-ben explicit [weak self]-et igényel, mivel a closure erősen hivatkozik a self-re.

Observer vs Publisher-Subscriber: mi a különbség

Observer (GoF) és Publisher-Subscriber (PubSub) — hasonló, de különböző minták. Az Observer-ben a kiadó közvetlenül értesíti az előfizetőket a metódusaik meghívásával. A kiadó tud az előfizetőkről (listát tárol). A PubSub-ban a kiadó és az előfizető nem tud egymásról — egy közvetítő (Event Bus, Message Queue, NotificationCenter) van közöttük. A kiadó üzenetet küld egy csatornára, az előfizető hallgatja a csatornát. A PubSub gyengébb csatolást biztosít.

PubSub példák mobil fejlesztésben — a NotificationCenter iOS-ben PubSub-nak tekinthető: a kiadó nem ismeri az előfizetőket — csak közzéteszi az értesítést. EventBus vagy Otto Android-ban (elavult). SharedFlow BroadcastChannel-nel — PubSub a Kotlin világában. Elosztott rendszerekben a PubSub RabbitMQ, Kafka, Google PubSub segítségével valósítható meg. Mobil fejlesztésben a PubSub moduláris architektúrában hasznos, ahol a modulok nem függhetnek egymástól.

Mit válasszunk — UI-frissítésekhez (ViewModel → View) használjon Observer-t (LiveData, StateFlow, @Published). Modulok közötti eseményekhez (hitelesítés, kijelentkezés, téma váltás) — PubSub-ot (SharedFlow, NotificationCenter, EventBus). Az Observer egyszerűbb és hatékonyabb egy képernyőn belül, a PubSub rugalmasabb a globális eseményekhez, de nehezebben debugolható az implicit függőségek miatt.

Gyakran Ismételt Kérdések

Miben különbözik a StateFlow a LiveData-tól?

A StateFlow egy platformfüggetlen típus a Kotlin Coroutines-ból, a LiveData az Android Lifecycle-hez kötött. A StateFlow támogatja a coroutines-t és operátorokat, Android nélkül tesztelhető. A LiveData automatikusan kezeli az előfizetést a LifecycleOwner segítségével. A Google a StateFlow-t ajánlja új, Kotlin + Compose projektekhez, a LiveData-t — Java kompatibilitáshoz.

Hogyan kerüljük el a memóriaszivárgást a NotificationCenter-rel?

Használjon [weak self]-et a handler closure-ban és hívja meg a removeObserver()-t a deinit-ben. Tároljon referenciát az observer-re (NSObjectProtocol) és távolítsa el az objektum megsemmisülésekor. A Combine-ban használjon AnyCancellable-t és store(in:)-t az automatikus leiratkozáshoz a DisposeBag felszabadításakor.

Használható az Observer SwiftUI-ban Combine nélkül?

Igen, a SwiftUI támogatja az ObservableObject-et @Published-del és @StateObject/@ObservedObject-del — ez egy beépített Observer implementáció. A @Published automatikusan értesíti a View-t a változásokról. A Combine nem kötelező: az ObservableObject a SwiftUI-ba épített objectWillChange Publisher-t használja. A Combine operátorokat ad hozzá a folyamok transzformálásához.

Mikor használjunk SharedFlow-t StateFlow helyett?

SharedFlow — egyszeri eseményekhez (navigáció, toast, Snackbar), ahol nem szükséges az aktuális érték. StateFlow — UI állapothoz (adatlista, betöltési állapot), ahol aktuális pillanatkép szükséges. A SharedFlow-nak nincs value tulajdonsága, és nem adja vissza az utolsó értéket az új előfizetőknek.

Mi a különbség a KVO és a Combine között iOS-ben?

A KVO egy elavult ObjC mechanizmus, @objc dynamic-ot igényel és csak NSObject-ből származó osztályokkal működik. A Combine egy modern Swift keretrendszer, típusbiztos, operátorokkal és SwiftUI integrációval. A Combine helyettesíti a KVO-t és a NotificationCenter-t. Az Apple a Combine-t ajánlja új projektekhez, a KVO-t — csak a régi kód támogatásához.

Összegzés

  • Observer — viselkedési minta az előfizetők értesítésére a változásokról
  • iOS NotificationCenter — PubSub implementáció elnevezett értesítésekkel
  • iOS Combine — reaktív keretrendszer Publisher és Subscriber segítségével
  • Android LiveData — lifecycle-aware Observer az Android Architecture Components-ből
  • Android StateFlow — reaktív állapottartó Compose-hoz és korutinokhoz
  • Memóriakezelés — kötelező leiratkozás a szivárgások megelőzésére
  • Observer vs PubSub — közvetlen előfizetés vs közvetítő a gyenge csatoláshoz

Kulcsrakész mobilalkalmazást fejlesztünk

Az IT Sectr 2017 óta készít iOS és Android alkalmazásokat induló vállalkozásoknak és vállalkozásoknak. Tanácsot adunk, és a legjobb megoldást javasoljuk.

Projekt megbeszélése

Olvassa el is