Observer — konsep kunci pola langganan perubahan

Penulis: IT Sectr Diterbitkan: 2026-02-17 Waktu membaca: 7 mnt

Observer — pola perilaku di mana satu objek (penerbit) memberi tahu banyak pelanggan tentang perubahan statusnya. Dalam pengembangan seluler, Observer mendasari mekanisme reaktif: UI berlangganan perubahan data dan diperbarui secara otomatis. Pola ini diimplementasikan di NotificationCenter pada iOS dan LiveData/Flow pada Android. Selengkapnya — di Refactoring Guru: Observer.

Poin Utama

  • Observer — pola langganan: satu penerbit, banyak pelanggan
  • NotificationCenter — implementasi bawaan Observer di iOS/macOS
  • Flow dan LiveData — implementasi reaktif Observer di Android
  • Push vs Pull — penerbit dapat mengirim data atau memberi tahu tentang peristiwa
  • Kebocoran memori — pelanggan harus berhenti berlangganan untuk mencegah kebocoran

Apa itu Observer: inti dari pola pengamat?

Observer (pengamat) — pola perilaku GoF yang mendefinisikan ketergantungan satu-ke-banyak antar objek. Ketika satu objek (Subject atau Observable) mengubah statusnya, semua objek yang bergantung (Observers) secara otomatis diberi tahu dan diperbarui. Pola ini mengimplementasikan kopling lemah: penerbit tidak mengetahui kelas konkret pelanggan — hanya bahwa mereka mengimplementasikan antarmuka Observer.

Struktur Observer mencakup antarmuka Subject dengan metode attach(), detach(), notify() dan antarmuka Observer dengan metode update(). ConcreteSubject menyimpan status dan daftar pelanggan. ConcreteObserver mengimplementasikan update() dan bereaksi terhadap perubahan. Dalam pengembangan seluler, implementasi klasik GoF jarang ditemukan — digantikan oleh mekanisme bawaan: NotificationCenter, Combine, Flow, LiveData, yang mengimplementasikan ide yang sama dengan API modern.

Model Push vs Pull — dalam model Push, Subject mengirim data ke semua pelanggan (NotificationCenter.post). Dalam model Pull, Subject hanya memberi tahu, dan pelanggan mengambil data sendiri. Android LiveData menggunakan Push (data diteruskan dalam observe()), RxJava/Flow mendukung kedua model. Pilihan tergantung pada tugas: Push lebih sederhana untuk pembaruan UI, Pull lebih efisien untuk volume data besar yang mungkin tidak ingin diterima pelanggan.

Observer di iOS: NotificationCenter, Combine dan KVO

NotificationCenter — mekanisme bawaan iOS/macOS untuk mengimplementasikan Observer. Penerbit mengirim Notification melalui NotificationCenter.default.post(name:, object:, userInfo:). Pelanggan mendaftar melalui addObserver(forName:, queue:, using:). NotificationCenter mendukung pemberitahuan bernama (Notification.Name) dan dapat meneruskan data apa pun di userInfo. UIKeyboardWillShowNotification, UIApplicationDidEnterBackgroundNotification — contoh sistem.

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

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

// Pelanggan
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 }
            // Pelanggan bereaksi terhadap peristiwa
            self?.loadProfile(userId: userId)
        }
        observers.append(observer)
    }

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

Combine framework — alternatif reaktif modern untuk NotificationCenter, tersedia sejak iOS 13. Publisher (NotificationCenter, URLSession.Timer) — penerbit, Subscriber (sink, assign) — pelanggan. Combine menambahkan operator (map, filter, combineLatest) untuk transformasi aliran data. @Published — property wrapper yang secara otomatis memberi tahu pelanggan tentang perubahan. Dalam MVVM dengan SwiftUI, Combine menggantikan NotificationCenter untuk menghubungkan ViewModel dan View.

KVO (Key-Value Observing) — mekanisme lama ObjC/Swift untuk mengamati properti individu objek. @objc dynamic var name: String — properti yang diamati. observe(.name) — langganan. KVO hanya berfungsi dengan kelas yang kompatibel dengan @objc dan warisan ObjC. Apple merekomendasikan Combine dan @Published daripada KVO di proyek baru. KVO tetap relevan untuk kompatibilitas UIKit di proyek hibrida.

Observer di Android: LiveData, StateFlow dan SharedFlow

LiveData — komponen Android Architecture Components untuk mengimplementasikan Observer. Kelas Observable yang memberi tahu pelanggan tentang perubahan data. LiveData memperhitungkan siklus hidup: pelanggan (LifecycleOwner) secara otomatis berhenti berlangganan saat dihancurkan. LiveData adalah model Push: data diteruskan dalam observe(). LiveData adalah blok bangunan dasar MVVM di Android sebelum pengenalan Jetpack Compose.

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

    override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
        viewModel.user.observe(viewLifecycleOwner) { user ->
            // Pelanggan bereaksi terhadap perubahan
            userName.text = user?.name
            userEmail.text = user?.email
        }
    }
}

StateFlow dan SharedFlow — tipe reaktif dari Kotlin Coroutines yang menggantikan LiveData di Jetpack Compose. StateFlow — observable state holder dengan nilai saat ini tetap. SharedFlow — hot flow yang dapat dikonfigurasi tanpa status, cocok untuk peristiwa satu kali (navigasi, toast). Kedua tipe terintegrasi erat dengan Compose: collectAsState(), collectAsEffect(). StateFlow wajib digunakan di proyek Android modern dengan Compose.

LiveData vs StateFlow — LiveData terikat pada Android Lifecycle, StateFlow independen platform. StateFlow mendukung coroutines, operator (map, filter) dan diuji tanpa dependensi Android. LiveData lebih sederhana untuk kompatibilitas Java. Google merekomendasikan StateFlow untuk proyek baru dengan Kotlin + Compose, LiveData — untuk mendukung proyek lama atau kode Java.

Mengelola langganan dan kebocoran memori

Kebocoran memori (memory leaks) — masalah utama Observer tanpa pengelolaan langganan yang benar. Jika pelanggan (Activity, Fragment, UIViewController) dihancurkan tetapi tidak berhenti berlangganan, penerbit tetap memegang referensi ke sana, dan garbage collector tidak dapat membebaskan memori. Di Android, LifecycleOwner (Activity/Fragment) harus memanggil removeObserver() atau menggunakan observe(viewLifecycleOwner). Di iOS — removeObserver di deinit atau disposeBag di Combine.

PlatformMekanisme ObserverBerhenti berlangganan otomatisBerhenti berlangganan manual
iOSNotificationCenterTidakremoveObserver() di deinit
iOSCombine (sink)Tidakstore(in: &bag) — DisposeBag
iOSKVOTidakremoveObserver() di deinit
AndroidLiveDataYa (LifecycleOwner)removeObserver() opsional
AndroidStateFlowMelalui viewModelScopecancel() Job saat berhenti berlangganan
AndroidRxJavaTidakdispose() di CompositeDisposable

Referensi lemah (weak reference) pada pelanggan — di blok langganan gunakan [weak self] di Swift dan rujuk ke lifecycle scope di Kotlin. LiveData secara otomatis mengelola langganan melalui LifecycleOwner — langganan hanya aktif ketika Lifecycle dalam status STARTED atau RESUMED. StateFlow di Compose menggunakan collectAsState() dengan mempertimbangkan lifecycle. NotificationCenter di iOS memerlukan [weak self] eksplisit, karena closure mereferensikan self secara kuat.

Observer vs Publisher-Subscriber: apa perbedaannya

Observer (GoF) dan Publisher-Subscriber (PubSub) — pola yang mirip tetapi berbeda. Di Observer, penerbit langsung memberi tahu pelanggan dengan memanggil metode mereka. Penerbit mengetahui pelanggan (menyimpan daftar). Di PubSub, penerbit dan pelanggan tidak saling mengetahui — ada perantara (Event Bus, Message Queue, NotificationCenter) di antara mereka. Penerbit mengirim pesan ke saluran, pelanggan mendengarkan saluran. PubSub memberikan kopling yang lebih longgar.

Contoh PubSub dalam pengembangan seluler — NotificationCenter di iOS dapat dianggap PubSub: penerbit tidak mengenal pelanggan — hanya memposting pemberitahuan. EventBus atau Otto di Android (usang). SharedFlow dengan BroadcastChannel — PubSub di dunia Kotlin. Dalam sistem terdistribusi, PubSub diimplementasikan melalui RabbitMQ, Kafka, Google PubSub. Untuk pengembangan seluler, PubSub berguna dalam arsitektur modular, di mana modul tidak boleh bergantung satu sama lain.

Apa yang harus dipilih — untuk pembaruan UI (ViewModel → View) gunakan Observer (LiveData, StateFlow, @Published). Untuk peristiwa antar modul (otorisasi, logout, perubahan tema) — PubSub (SharedFlow, NotificationCenter, EventBus). Observer lebih sederhana dan efisien dalam satu layar, PubSub lebih fleksibel untuk peristiwa global tetapi lebih sulit di-debug karena dependensi implisit.

Pertanyaan yang Sering Diajukan

Apa perbedaan StateFlow dengan LiveData?

StateFlow adalah tipe independen platform dari Kotlin Coroutines, LiveData terikat pada Android Lifecycle. StateFlow mendukung coroutines dan operator, diuji tanpa Android. LiveData secara otomatis mengelola langganan melalui LifecycleOwner. Google merekomendasikan StateFlow untuk proyek baru dengan Kotlin + Compose, LiveData — untuk kompatibilitas Java.

Bagaimana cara menghindari kebocoran memori dengan NotificationCenter?

Gunakan [weak self] di closure handler dan panggil removeObserver() di deinit. Simpan referensi ke observer (NSObjectProtocol) dan hapus saat objek dihancurkan. Di Combine, gunakan AnyCancellable dan store(in:) untuk berhenti berlangganan otomatis saat DisposeBag dibebaskan.

Bisakah Observer digunakan di SwiftUI tanpa Combine?

Ya, SwiftUI mendukung ObservableObject dengan @Published dan @StateObject/@ObservedObject — ini adalah implementasi bawaan Observer. @Published secara otomatis memberi tahu View tentang perubahan. Combine tidak wajib: ObservableObject menggunakan Publisher objectWillChange yang tertanam di SwiftUI. Combine menambahkan operator untuk transformasi aliran.

Kapan menggunakan SharedFlow daripada StateFlow?

SharedFlow — untuk peristiwa satu kali (navigasi, toast, Snackbar) di mana nilai saat ini tidak diperlukan. StateFlow — untuk status UI (daftar data, progres pemuatan) di mana snapshot saat ini diperlukan. SharedFlow tidak memiliki properti value dan tidak mengembalikan nilai terakhir ke pelanggan baru.

Apa perbedaan antara KVO dan Combine di iOS?

KVO adalah mekanisme ObjC lama, memerlukan @objc dynamic dan hanya berfungsi dengan kelas yang mewarisi NSObject. Combine adalah framework Swift modern, type-safe, dengan operator dan integrasi dengan SwiftUI. Combine menggantikan KVO dan NotificationCenter. Apple merekomendasikan Combine untuk proyek baru, KVO — hanya untuk mendukung kode lama.

Ringkasan

  • Observer — pola perilaku untuk memberi tahu pelanggan tentang perubahan
  • iOS NotificationCenter — implementasi PubSub dengan pemberitahuan bernama
  • iOS Combine — framework reaktif dengan Publisher dan Subscriber
  • Android LiveData — lifecycle-aware Observer dari Android Architecture Components
  • Android StateFlow — state holder reaktif untuk Compose dan coroutine
  • Manajemen memori — berhenti berlangganan wajib untuk mencegah kebocoran
  • Observer vs PubSub — langganan langsung vs perantara untuk kopling lemah

Kami akan mengembangkan aplikasi seluler turnkey

IT Sectr membuat aplikasi iOS dan Android untuk startup dan bisnis sejak 2017. Kami akan memberi saran dan mengusulkan solusi terbaik.

Diskusikan proyek

Baca juga