버그 잡이

[디자인 패턴] 옵저버 패턴이란? #리스너 #콜백 본문

카테고리 없음

[디자인 패턴] 옵저버 패턴이란? #리스너 #콜백

버그잡이 2020. 6. 20. 15:14

1. 옵저버 패턴이란?

옵저버 패턴은 객체의 상태 변화를 관찰하는 관찰자들, 즉 옵저버를 객체에 등록하여 상태 변화가 있을 때마다 객체가 옵저버에게 통지하도록 하는 디자인 패턴이다.

출처 : 위키백과

 

객체에 옵저버를 등록하고 상태 변화가 있을 때마다 옵저버를 발동시키는 패턴입니다.

 

 

 

2. 왜 이런 옵저버 패턴을 쓸까?

 

"이벤트 기반 프로그래밍을 위해서 사용한다."

 

 

*이벤트 기반 프로그래밍이란?

사용자의 명령, 마우스 클릭과 같은 입력 등의 사건에 따라 제어 흐름이 결정되어 일을 하도록 만들어진 프로그래밍 방식입니다.

 

안드로이드 앱을 예로 들어보면, 버튼에 대한 클릭은 clickListener를 통해서 인식하여 처리합니다.

즉, 이 리스너를 통해서 받은 상태에 따라 처리되는 데이터가 달라지고 추후 동작이 달라지는 것입니다.

 

 

 

3. 이런 패턴이 어떻게 가능할까?

 

Interface를 활용합니다.

 

 

(코드를 통해서 구체적으로 살펴보겠습니다.)

 

//인터페이스 : 옵저버, 리스너
interface EventListener {
	fun onEvent(count : Int)
}


//ClassB
class ClassB(var listener : EventListener){

	fun count(){
    	for(i in 0..100){
        	listener.onEvent(i)	//count 함수가 실행될때마다 인터페이스의 onEvent를 발생시킨다.
    	}
    }
}


//ClassA
class ClassA : EventListener{

    //EventListener의 onEvent 함수를 구체적으로 구현한다.
    //ClassB에서 onEvent가 발생하면 ClassA로 이벤트가 넘어와 구현한 로직으로 수행이 되는데 이를 callback 이라고 한다.
	override fun onEvent(num: Int){		
    	print(num.toString())
    }
    
    fun start(){
    	val counter = ClassB(this)
        counter.count()
    }
}

참고 : www.youtube.com/watch?v=GxZWb5Whq7w&list=PLQdnHjXZyYadiw5aV3p6DwUdXV2bZuhlN&index=17

 

 

ClassB에 옵저버를 등록하고 ClassB에서는 특정 변화(count())가 있을때마다 옵저버에게 신호를 줍니다.

여기서 끝난다면 큰 의미가 없겠지요.

ClassA는 옵저버인 interface를 impl하여 옵저버 발동시 수행될 로직을 구현합니다.

 

-> 즉, 이벤트는 B에서 발생하지만 그에 따른 구체적인 로직은 A에서 처리할 수 있는 것입니다.

 

B는 "Button 클래스"가 되고 A는 "Activity 클래스"가 될 수 있습니다.

 

이렇게 이벤트 발생지와 구현부를 따로 따로 가져가는 패턴은 장점이 있습니다.

만약 버튼 이벤트를 버튼 class에서 처리한다고 생각해봅시다.

버튼 클릭시 새로운 액티비티를 띄우고 싶은데 그럴려면 안드로이드에서는 context도 필요하고 다른 부가적인 자원들이 필요합니다. 그렇기 때문에 여러 객체들을 버튼 클래스 안에서 새롭게 생성을 해야 이 작업이 가능하겠지요.

하지만 버튼 클릭시 이벤트 신호만 주고 처리는 activity클래스에서 한다면 activity에 있는 자원을 그냥 활용하면 되는 것이지요.

 

이렇게 옵저버 패턴을 활용하면 각 클래스의 자원을 잘 활용하여 메모리 낭비를 피할 수 있고 불필요한 코드를 줄일 수 있습니다. 

(버튼의 예제 뿐만 아니라 리사이클러뷰 어댑터와 액티비티간 클릭 리스너 등 다양한 부분에 응용가능합니다)

 

 

 

 

용어 정리

 

옵저버 vs 리스너

 

위에서 배운 패턴이 옵저버 패턴이고

이러한 옵저버 패턴을 활용해 만든 것이 Listener interface입니다.

(옵저버 패턴이 더 상위 개념이라고 할 수 있겠죠)

 

 

옵저버 vs 콜백

 

위 사례를 보면 B에서 이벤트가 발생하면 A가 이를 감지하고 동작을 수행하는데

이렇게 A가 신호를 받는 것을 콜백이라고 합니다.

"Call in the back" 으로 즉 뒤에서 호출을 해주는 것입니다.

지금은  A가 메인 클래스이기 때문에 A에서 함수를 call 하는 것이 일반적이지만 위와 같은 경우 뒤에 있는 B에서 call을 하는 것이지요

 

반응형
Comments