본문 바로가기

Language/Kotlin

[Kotlin] 익명객체와 옵저버 패턴

728x90
반응형

옵저버

: 이벤트가 일어나는 것을 감시하는 감시자

 

ex. 안드로이드

키의 입력, 터치의 발생, 데이터의 수신 등 함수로 직접 요청하지 않았지만 시스템 또는 루틴에 의해서 발생하게 되는 동작을 ‘이벤트’라고 부르며 이 이벤트가 발생할 때마다 즉각적으로 처리할 수 있도록 만드는 프로그래밍 패턴을 옵저버 패턴이라고 부른다.

 

옵저버 패턴을 구현할 때는 두 개의 클래스가 필요하다.

  • 이벤트를 수신하는 클래스 (class A)
  • 이벤트를 발생 및 전달하는 클래스 (class B)

어떻게 통신?

B에서 이벤트가 발생할 때 A에 있는 이벤트를 처리하는 함수를 호출하여 알려준다.

→ 문제 : A의 필요에 따라 B의 인스턴스를 생성하여 사용하기 때문에 A는 B를 직접 참조할 수 있지만 B는 A를 참조할 방법이 없다.

→ 해결책: 두 클래스 사이에 인터페이스를 끼워넣는다.

 

B에서는 자신의 이벤트를 받을 수 있는 인터페이스를 만들어 공개하고, A는 이를 구현하여 B에 넘겨주면 인터페이스만 알아도 이벤트를 넘겨줄 수 있다. 이때 이 인터페이스를 ‘observer’ 또는 코틀린에서는 ‘listener’라고 부르며 이렇게 이벤트를 넘겨주는 행위를 ‘callback’이라고 한다.

fun main(){
    EventPrinter().start()
}

interface EventListener{
    fun onEvent(count: Int)  // * 리스너를 통해 이벤트를 반환하는 함수 이름은 관례적으로 on(행위)라는 규칙을 따른다.
}

class Counter(var listener: EventListener){  // 숫자를 카운트하며 5의 배수마다 이벤트 발생시킴
    fun count(){
        for(i in 1..100){
            if(i % 5 == 0) listener.onEvent(i)
        }
    }
}

class EventPrinter: EventListener{  // 이벤트를 수신해서 출력
    override fun onEvent(count: Int){
        print("${count}-")
    }

    fun start(){
        val counter = Counter(this)
        counter.count()
    }
}

// 출력: 5-10-15-20-25-30-35-40-45-50-55-60-65-70-75-80-85-90-95-100-

this는 EventPrinter 객체 자신을 나타내지만 받는 쪽에서 EventListener만 요구했기 때문에 EventListener 구현부만 넘겨주게 된다.

→ 객체지향의 다형성 : 상속받아 만들어진 클래스는 수퍼 클래스의 기능을 포함하여 제작되었으므로 수퍼클래스에서 정의한 부분만 따로 넘겨줄 수 있다.

 

익명객체

: 이름이 없는 객체

 

EventPrinter가 EventListener을 상속받아 구현하지 않고 임시로 만든 별도의 EventListener 객체를 대신 넘겨줄 수도 있다.

fun main(){
    EventPrinter().start()
}

interface EventListener{
    fun onEvent(count: Int) 
}

class Counter(var listener: EventListener){  
        for(i in 1..100){
            if(i % 5 == 0) listener.onEvent(i)
        }
    }
}

class EventPrinter{
    fun start(){
        val counter = Counter(object: EventListener{
            override fun onEvent(count: Int){
                print("${count}-")
            }
        })
    }
}

// 출력: 5-10-15-20-25-30-35-40-45-50-55-60-65-70-75-80-85-90-95-100-
728x90
반응형

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

[Kotlin] 제너릭  (0) 2023.09.17
[Kotlin] 클래스의 다형성  (0) 2023.09.10
[Kotlin] 오브젝트  (0) 2023.09.09
[Kotlin] 스코프 함수  (0) 2023.09.07
[Kotlin] 고차함수와 람다함수  (0) 2023.09.07