Observer pattern 구조 및 사용

2020. 12. 27. 16:06android

1. observer 패턴이란?


영어로 "관찰하다"라는 뜻을 갖는 observe는 개발에서도 무언가를 관찰하는데 사용됩니다. 여기서 무언가는 변수를 의미하며, 변수의 type은 primitive type이든 reference type이든 상관없습니다. 

 

쉽게 설명하기 위해 아래 그림을 예시로 들어보겠습니다.  

 

2. Observer의 구조


A라는 변수에 10이 담겨져 있고 이를 옵저버가 관찰하고 있습니다. 여기서 관찰자의 역할은 A의 값이 변경되면 A의 변화를 그 즉시 알아채는 역할을 합니다. 때문에 A에 변화에 대한 적절한 행동을 취하도록 만드는 것을 "observer pattern"이라고 합니다.

 

그렇다면 "적절한 행동을 취하도록"하는 것을 코드상으로 만들어야합니다. 

<해당 포스팅 코드들은 모두 Kotlin으로 작성되었습니다>

 

 

그리고 이를 상속받은 A,B 옵저버들을 추상클래스로 만듭니다.

ps)추상 클래스로 만든 이유는 A, B 옵저버 객체를 할당 할 곳에서 observe 메서드를 구현할 것이기 때문에 추상클래스로 만들었습니다!! 일반적으로 "적절하게 행동"을 만드는 부분은 자주 변경될 수 있는 부분이기 때문이죠!

 

 

 

 

이후 옵저버들을 관리할 ObserverManager class입니다. 해당 클래스는 선언된 옵저버들을 관리하는 역할을 할 뿐더러, 옵저버가 관찰하고 있는 값이 변경되면 update를 진행하기 위해 만든 class입니다. 말 그대로 "적절한 행동을 취하기 위한" 것을 만든 것입니다. 

 

 

ObserverManager class를 조금 더 설명해 보겠습니다. 옵저버를 관리하기 위해서 저는 HashMap을 사용하였습니다.

map의 구조는 key와 value로 이루어져 있기 때문에 key값은 항상 고유해야 합니다. 따라서 observer 객체가 메모리에 할당될 때, 부여받은 값을 map의 key값으로 사용합니다. 그리고 해당 key에 매칭이 되는 value로 observer 객체를 저장해 놓으면 고유한 key를 통하여 observer를 얻을 수 있고 또, 저장할 수 있기 때문에 HashMap으로 옵저버 객체들을 관리하도록 하였습니다.

 

이후, 옵저버 객체를 맵에 추가하기 위해서 addObserver() 메서드를 사용합니다. 추가적으로 이해를 돕기 위해서 map에 이미 저장되어 있는지를 체크 후(말 그대로 이해를 돕는 부분이기 때문에 지워도 상관없습니다), observe() 를 실행합니다.

 

여기서 observe() 메서드가 바로 "적절한 행동"을 취하도록 핸들링한 코드입니다. observe 메서드의 구현은 해당 클래스에 존재하지 않습니다. 그 이유는 바로 파라미터 객체가 인터페이스인 Observer이기 때문이죠. 즉 어디선가 구현한 Observe 객체의 observe 메서드를 사용하겠다는 의미입니다. 

 

그럼 그 어디선가에 대한 구현을 해보도록 하겠습니다. 

 

먼저 A,B 옵저버들을 생성하고 이름을 각각 A,B로 주었습니다. 본래 인터페이스는 객체화가 불가능하지만, anonymous class를 통해 객체화 할 수 있기 때문에 해당 코드처럼 객체화가 가능합니다. 여기서 구현된 observe()가 addObserver()에서 사용되는 observe()입니다. 

 

따라서 observerManager 객체는 A,B 옵저버들을 저장하고 addObserver()를 통해 구현된 observe()를 실행시킴으로써, 변화를 감지하게 됩니다. 

 

3.결과


실행 결과입니다. 먼저, 객체화된 A,B를 addObserver()하는 각각 구현한 observe()를 실행시킵니다. 

이후 B 옵저버의 네임을 변경하고 다시 addObserver()하면 이미 B옵저버가 map에 저장되어 있기 때문에 이미 존재한다는 문구가 나타나고, 이내 변경된 옵저버를 키에 맞는 value로 바꿈으로써 업데이틀 완료합니다. 

 

이렇게 옵저버 패턴에 대해서 알아봤습니다. 다음 편에서는 IDE에 내장된 observer를 사용해 보겠습니다.