Observer — klíčové pojmy vzoru předplatného na změny

Autor: IT Sectr Publikováno: 2026-02-17 Doba čtení: 7 min

Observer — behaviorální vzor, ve kterém jeden objekt (vydavatel) informuje mnoho předplatitelů o změnách svého stavu. V mobilním vývoji je Observer základem reaktivních mechanismů: UI se přihlásí k odběru změn dat a automaticky se aktualizuje. Vzor je implementován v NotificationCenter na iOS a LiveData/Flow na Android. Více — na Refactoring Guru: Observer.

Hlavní body

  • Observer — vzor předplatného: jeden vydavatel, mnoho předplatitelů
  • NotificationCenter — vestavěná implementace Observer v iOS/macOS
  • Flow a LiveData — reaktivní implementace Observer v Android
  • Push vs Pull — vydavatel může odesílat data nebo informovat o událostech
  • Úniky paměti — předplatitelé se musí odhlásit, aby zabránili únikům

Co je Observer: podstata vzoru pozorovatel?

Observer (pozorovatel) — behaviorální vzor GoF definující závislost «jeden k mnoha» mezi objekty. Když jeden objekt (Subject nebo Observable) změní stav, všechny závislé objekty (Observers) jsou automaticky informovány a aktualizovány. Vzor implementuje volnou vazbu: vydavatel nezná konkrétní třídy předplatitelů — pouze to, že implementují rozhraní Observer.

Struktura Observer zahrnuje rozhraní Subject s metodami attach(), detach(), notify() a rozhraní Observer s metodou update(). ConcreteSubject ukládá stav a seznam předplatitelů. ConcreteObserver implementuje update() a reaguje na změny. V mobilním vývoji se klasická implementace GoF vyskytuje zřídka — nahrazují ji vestavěné mechanismy: NotificationCenter, Combine, Flow, LiveData, které implementují stejnou myšlenku s moderním API.

Model Push vs Pull — v modelu Push posílá Subject data všem předplatitelům (NotificationCenter.post). V modelu Pull Subject pouze informuje a předplatitel si data sám vyžádá. Android LiveData používá Push (data jsou předávána v observe()), RxJava/Flow podporují oba modely. Volba závisí na úkolu: Push je jednodušší pro UI aktualizace, Pull je efektivnější pro velké objemy dat, které předplatitel možná nechce přijímat.

Observer v iOS: NotificationCenter, Combine a KVO

NotificationCenter — vestavěný mechanismus iOS/macOS pro implementaci Observer. Vydavatel odesílá Notification prostřednictvím NotificationCenter.default.post(name:, object:, userInfo:). Předplatitel se registruje pomocí addObserver(forName:, queue:, using:). NotificationCenter podporuje pojmenovaná oznámení (Notification.Name) a může předávat libovolná data v userInfo. UIKeyboardWillShowNotification, UIApplicationDidEnterBackgroundNotification — systémové příklady.

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

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

// Předplatitel
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 }
            // Předplatitel reaguje na událost
            self?.loadProfile(userId: userId)
        }
        observers.append(observer)
    }

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

Combine framework — moderní reaktivní alternativa k NotificationCenter, dostupná od iOS 13. Publisher (NotificationCenter, URLSession.Timer) — vydavatel, Subscriber (sink, assign) — předplatitel. Combine přidává operátory (map, filter, combineLatest) pro transformaci datového toku. @Published — property wrapper, který automaticky informuje předplatitele o změnách. V MVVM se SwiftUI nahrazuje Combine NotificationCenter pro propojení ViewModel a View.

KVO (Key-Value Observing) — starý mechanismus ObjC/Swift pro pozorování jednotlivých vlastností objektů. @objc dynamic var name: String — pozorovaná vlastnost. observe(.name) — předplatné. KVO funguje pouze s @objc-kompatibilními třídami a dědictvím ObjC. Apple doporučuje Combine a @Published místo KVO v nových projektech. KVO zůstává relevantní pro kompatibilitu UIKit v hybridních projektech.

Observer v Android: LiveData, StateFlow a SharedFlow

LiveData — komponenta Android Architecture Components pro implementaci Observer. Třída Observable, která informuje předplatitele o změnách dat. LiveData zohledňuje životní cyklus: předplatitelé (LifecycleOwner) se automaticky odhlašují při zničení. LiveData je model Push: data jsou předávána v observe(). LiveData je základní stavební blok MVVM v Android před zavedením Jetpack Compose.

kotlin
// ViewModel — vydavatel
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 — předplatitel
class UserFragment : Fragment() {
    private val viewModel: UserViewModel by viewModels()

    override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
        viewModel.user.observe(viewLifecycleOwner) { user ->
            // Předplatitel reaguje na změny
            userName.text = user?.name
            userEmail.text = user?.email
        }
    }
}

StateFlow a SharedFlow — reaktivní typy z Kotlin Coroutines, které nahradily LiveData v Jetpack Compose. StateFlow — observable state holder s pevnou aktuální hodnotou. SharedFlow — konfigurovatelný hot flow bez stavu, vhodný pro jednorázové události (navigace, toasty). Oba typy jsou úzce integrovány s Compose: collectAsState(), collectAsEffect(). StateFlow je povinný v moderních Android projektech s Compose.

LiveData vs StateFlow — LiveData je vázán na Android Lifecycle, StateFlow je platformově nezávislý. StateFlow podporuje coroutines, operátory (map, filter) a testuje se bez Android závislostí. LiveData je jednodušší pro kompatibilitu s Java. Google doporučuje StateFlow pro nové projekty s Kotlin + Compose, LiveData — pro podporu starých projektů nebo Java kódu.

Správa předplatných a úniky paměti

Úniky paměti (memory leaks) — hlavní problém Observer bez správné správy předplatných. Pokud je předplatitel (Activity, Fragment, UIViewController) zničen, ale není odhlášen, vydavatel nadále drží referenci na něj a garbage collector nemůže uvolnit paměť. V Android musí LifecycleOwner (Activity/Fragment) zavolat removeObserver() nebo použít observe(viewLifecycleOwner). V iOS — removeObserver v deinit nebo disposeBag v Combine.

PlatformaMechanismus ObserverAutomatické odhlášeníRuční odhlášení
iOSNotificationCenterNeremoveObserver() v deinit
iOSCombine (sink)Nestore(in: &bag) — DisposeBag
iOSKVONeremoveObserver() v deinit
AndroidLiveDataAno (LifecycleOwner)removeObserver() volitelně
AndroidStateFlowPřes viewModelScopecancel() Job při odhlášení
AndroidRxJavaNedispose() v CompositeDisposable

Slabá reference (weak reference) u předplatitelů — v bloku předplatného použijte [weak self] v Swift a odkazujte se na lifecycle scope v Kotlin. LiveData automaticky spravuje předplatné prostřednictvím LifecycleOwner — předplatné je aktivní pouze když je Lifecycle ve stavu STARTED nebo RESUMED. StateFlow v Compose používá collectAsState() s ohledem na lifecycle. NotificationCenter v iOS vyžaduje explicitní [weak self], protože closure silně referencuje self.

Observer vs Publisher-Subscriber: jaký je rozdíl

Observer (GoF) a Publisher-Subscriber (PubSub) — podobné, ale odlišné vzory. V Observer vydavatel přímo informuje předplatitele voláním jejich metod. Vydavatel ví o předplatitelích (ukládá seznam). V PubSub vydavatel a předplatitel nevědí jeden o druhém — mezi nimi je zprostředkovatel (Event Bus, Message Queue, NotificationCenter). Vydavatel posílá zprávu na kanál, předplatitel poslouchá kanál. PubSub poskytuje volnější vazbu.

Příklady PubSub v mobilním vývoji — NotificationCenter v iOS lze považovat za PubSub: vydavatel nezná předplatitele — pouze zveřejňuje oznámení. EventBus nebo Otto v Android (zastaralé). SharedFlow s BroadcastChannel — PubSub ve světě Kotlin. V distribuovaných systémech je PubSub implementován pomocí RabbitMQ, Kafka, Google PubSub. Pro mobilní vývoj je PubSub užitečný v modulární architektuře, kde moduly na sobě nemají záviset.

Co vybrat — pro UI aktualizace (ViewModel → View) použijte Observer (LiveData, StateFlow, @Published). Pro události mezi moduly (autorizace, odhlášení, změna motivu) — PubSub (SharedFlow, NotificationCenter, EventBus). Observer je jednodušší a efektivnější v rámci jedné obrazovky, PubSub je flexibilnější pro globální události, ale obtížnější na ladění kvůli implicitním závislostem.

Často kladené otázky

Čím se liší StateFlow od LiveData?

StateFlow je platformově nezávislý typ z Kotlin Coroutines, LiveData je vázán na Android Lifecycle. StateFlow podporuje coroutines a operátory, testuje se bez Android. LiveData automaticky spravuje předplatné prostřednictvím LifecycleOwner. Google doporučuje StateFlow pro nové projekty s Kotlin + Compose, LiveData — pro kompatibilitu s Java.

Jak se vyhnout únikům paměti s NotificationCenter?

Použijte [weak self] v closure handleru a zavolejte removeObserver() v deinit. Uchovávejte referenci na observer (NSObjectProtocol) a odstraňte ji při zničení objektu. V Combine použijte AnyCancellable a store(in:) pro automatické odhlášení při uvolnění DisposeBag.

Lze použít Observer v SwiftUI bez Combine?

Ano, SwiftUI podporuje ObservableObject s @Published a @StateObject/@ObservedObject — to je vestavěná implementace Observer. @Published automaticky informuje View o změnách. Combine není povinný: ObservableObject používá Publisher objectWillChange zabudovaný do SwiftUI. Combine přidává operátory pro transformaci toků.

Kdy použít SharedFlow místo StateFlow?

SharedFlow — pro jednorázové události (navigace, toasty, Snackbar), kde není potřeba aktuální hodnota. StateFlow — pro stav UI (seznam dat, průběh načítání), kde je potřeba aktuální snímek. SharedFlow nemá vlastnost value a nevrací poslední hodnotu novým předplatitelům.

Jaký je rozdíl mezi KVO a Combine v iOS?

KVO je zastaralý mechanismus ObjC, vyžaduje @objc dynamic a funguje pouze s třídami dědícími z NSObject. Combine je moderní Swift framework, typově bezpečný, s operátory a integrací se SwiftUI. Combine nahrazuje KVO a NotificationCenter. Apple doporučuje Combine pro nové projekty, KVO — pouze pro podporu starého kódu.

Shrnutí

  • Observer — behaviorální vzor pro informování předplatitelů o změnách
  • iOS NotificationCenter — implementace PubSub s pojmenovanými oznámeními
  • iOS Combine — reaktivní framework s Publisher a Subscriber
  • Android LiveData — lifecycle-aware Observer z Android Architecture Components
  • Android StateFlow — reaktivní state holder pro Compose a korutiny
  • Správa paměti — povinné odhlášení pro prevenci úniků
  • Observer vs PubSub — přímé předplatné vs zprostředkovatel pro volnou vazbu

Vyvineme mobilní aplikaci na klíč

IT Sectr vytváří aplikace pro iOS a Android pro startupy a podniky od roku 2017. Poradíme vám a navrhneme nejlepší řešení.

Prodiskutovat projekt

Přečtěte si také