okuzawatsの日記

Android / Kotlin Enthusiast 🤖

Observer Pattern with Kotlin

This code is awful. You have to know obserber’s detail and call update method one by one. What if observers increase or decrease? You have to maintain them. This is a nightmare.

fun main(args: Array<String>) {
    val someClass1 = SomeClass1()
    val someClass2 = SomeClass2()
    val someClass3 = SomeClass3()

    someClass1.updateSomeClass1() // SomeClass 1 is updated!
    someClass2.updateSomeClass2() // SomeClass 2 is updated!
    someClass3.updateSomeClass3() // SomeClass 3 is updated!
}

class SomeClass1 {
    fun updateSomeClass1() = println("SomeClass 1 is updated!")
}

class SomeClass2 {
    fun updateSomeClass2() = println("SomeClass 2 is updated!")
}

class SomeClass3 {
    fun updateSomeClass3() = println("SomeClass 3 is updated!")
}

With Observer Pattern, you do not have to know observer’s detail. All you have to know is that observers have same interface.

You can attach the observers to subject like below. Once you attached it, subject can notify observers to update without knowing its detail.

fun main(args: Array<String>) {
    val subject = Subject()

    val observer1 = Observer1().also {
        subject.attach(it)
    }

    val observer2 = Observer2().also {
        subject.attach(it)
    }

    val observer3 = Observer3().also {
        subject.attach(it)
    }

    subject.notificate()
    // Observer 1 is updated!
    // Observer 2 is updated!
    // Observer 3 is updated!
}

If you’d like to stop updating a observer, you can detach it.

    subject.detach(observer3)

    subject.notificate()
    // Observer 1 is updated!
    // Observer 2 is updated!

Subject have a collection of observers that have same interface. You can add or remove the observer from collection. Also, you can update observers using a loop.

class Subject {
    private val observers = mutableListOf<Observer>()

    fun attach(observer: Observer) = observers.add(observer)

    fun detach(observer: Observer) = observers.remove(observer)

    fun notificate() = observers.forEach { observer ->
        observer.update()
    }
}

interface Observer {
    fun update()
}

Observer have the same interface, so subject can updated through the interface withou knowing the detail of observers. On the other hand, observers do not know anything about the subject.

class Observer1: Observer {
    override fun update() = println("Observer 1 is updated!")
}

class Observer2: Observer {
    override fun update() = println("Observer 2 is updated!")
}

class Observer3: Observer {
    override fun update() = println("Observer 3 is updated!")
}

#Kotlin #Design

About me 😎

profile

茨城県つくば市在住のソフトウェアエンジニアです。専門領域はAndroidアプリ開発で、特にアーキテクチャに興味があります。某社でAndroidアプリ開発のテックリードをしています。

Jetpack ComposeによるAndroid MVVMアーキテクチャ入門の著者です。

👉 もっと詳しく

Writing 📝

Android MVVMアーキテクチャ入門

Androidアプリ開発の初学者に向けた、MVVM(Model-View-ViewModel)アーキテクチャの入門書を書きました。初学者の方を確実にネクストレベルに引き上げる技術書です。

👉 もっと詳しく

See Also 👀