Coding Memo

Kotlin 옵저버 패턴 본문

Language/Kotlin

Kotlin 옵저버 패턴

minttea25 2021. 1. 3. 14:39

Observer Pattern

 

어떤 이벤트가 발생했을 때 알맞은 동작을 하기 위해 계속해서 관찰(observe) 한다고 생각하자.

이를 Observer Pattern이라고 한다. 

이벤트를 넘겨주는 행위를 'callback'이라고 한다.

 

Observer Pattern 구현을 위해서는 이벤트를 발생시키고 전달하는 클래스와 이벤트를 수신하고 동작을 하는 class가 필요하다.

이를 위해 interface를 사용하는데, 코틀린과 안드로이드(Java)에서는 listener라는 이름의 interface가 더 친숙할 수 있다.

(안드로이드 이벤트 처리 시 리스너(listener)를 사용한다는 것은 많이 들어보았다.)

fun main() {
    EventGen().touch()
}

interface EventListener {
    fun touchEvent(x: Int, y:Int)
}

class EventSet(var listener: EventListener) {
    private val random = Random
    fun doTouch() {
        val a = random.nextInt(1080)
        val b = random.nextInt(1080)
        listener.touchEvent(a, b)
    }
}

class EventGen : EventListener {
    override fun touchEvent(x: Int, y: Int) {
        println("Touched: x(${x}), y(${y})")
    }
    fun touch() {
        val e = EventSet(this)
        for (i in 1..5) {
            e.doTouch()
        }
    }
}

Listener 이벤트 예시 출력 결과

EventGen 클래스에서의 this는 자기 자신을 가리킨다. 그러나 EventSet 클래스의 생성자의 인자가 EventListener 뿐이므로 this가 자기 자신을 가리킨다고 하더라도 모든 내용을 넘겨주는 것이 아니라 EventListener 인터페이스 부분의 내용만 넘겨주게 된다. (객체지향의 다형성) (슈퍼클래스나 인터페이스가 가지고 있는 내용만을 넘겨준다.)

 

참고: 코틀린은 Java와 동일하게 익명 객체 (Anonymous Object)도 가능하기 때문에 아래와 같이 인터페이스의 상속 없이 사용할 수 있다.

class EventGen {
    fun touch() {
        val e = EventSet(object: EventListener {
            override fun touchEvent(x: Int, y: Int) {
                println("Touched: x(${x}), y(${y})")
            }
        })
        for (i in 1..5) {
            e.doTouch()
        }
    }
}

결과는 위와 같다.

'Language > Kotlin' 카테고리의 다른 글

Kotlin 캐스팅  (0) 2021.01.06
Kotlin 문자열  (0) 2021.01.05
Kotlin 오브젝트  (0) 2021.01.03
Kotlin 스코프 함수  (0) 2021.01.02
Kotlin 인터페이스  (0) 2021.01.02