옵저버 패턴(Observer Pattern)
한국의 20-30대 남성에게 옵저버를 물어본다면
대부분이 꾸물거리며 음흉하게 남의 기지를 훔쳐보는 프로토스의 옵저버를 떠올리실 것이다.
이 옵저버가 프로토스 뿐만 아니라 유니티에서도 많이 쓰이는 디자인 패턴중에 하나라고 해서 정리를 해보았다.
옵저버 패턴이란?
나도 이곳저곳 영상과 블로그 글을 참고하여 공부를 하고 왔지만 뭐든 딱 뭐라고 정의하는것이 참 어렵다.
옵저버 패턴은 Observer라는 뜻대로 감시자들이 있다.
이 감시자들이 계속 감시를 하다가 변화가 일어나면 이 변화에 맞는 행동들을 해준다.(콜백)
난 여러곳에 정리 되어 있는 정의만 보고나서
내가 포트폴리오를 만들면서 알림시스템을 썼을때의 방법일까? 라고 생각을 했었는데 달랐다.
난 비효율적으로 업데이트문에서 계속 큐에 메세지가 들어왔는지 확인을 했지만,
옵저버 패턴은 계속 호출 할 필요 없이 이벤트가 발생되어 주제(subject) 객체에 변화가 생겼다는 것을 알려주기만 하면 등록된 옵저버들이 그에 맞는 행동을 한다.
알게 돼서 다행일정도로 정말 유용하게 쓸 수 있는 디자인 패턴인거 같고, 내가 어떤것을 구현하기 위해 했던 고민들을 상당히 덜어 준 것 같다.
글로만 보면 어려우니 구현을 한번 해보자.
옵저버 패턴의 구현(예제)
그냥 내가 이해한대로 구현을 해본거라 맞는 예제일진 모르겠다.
테스트를 위해 UI를 대충 만들었다.
왕의 말씀을 적어서 전달하면 1번,2번,3번 부하가 알아서 왕의 메세지를 띄운다.
public interface ISubject
{
public void AddObserver(IObserver observer);
public void RemoveObserver(IObserver observer);
public void NotifyToObserver();
}
public interface IObserver
{
public void UpdateKingNotify(string notify);
}
인터페이스를 2개 만들어줬다.
변화를 일으키고 옵저버들에게 자신의 변화를 알려줄 객체에 붙여줄 ISubject 인터페이스
그리고 그 변화를 받아서 행동을 취할 IObserver 인터페이스
public class King : MonoBehaviour, ISubject
{
public List<IObserver> Observers = new List<IObserver>();
public InputField myInput;
public void AddObserver(IObserver observer)
{
Observers.Add(observer);
}
public void RemoveObserver(IObserver observer)
{
Observers.Remove(observer);
}
public void NotifyToObserver()
{
if(Observers.Count != 0)
{
for(int i=0;i<Observers.Count;i++)
{
Observers[i].UpdateKingNotify(myInput.text);
}
}
}
}
왕 클래스는 Isubject 인터페이스를 상속받아서 3가지 함수를 전부 구현해줬다.
1. 일단 옵저버들을 등록할 Observers 리스트를 선언했다.
2. AddObserver 함수에서는 옵저버를 등록시킨다.
3. RemoveObserver 함수에서는 옵저버를 삭제한다.
4. IObserver를 상속받은 클래스들에서 어떻게 함수를 만드느냐에 따라 적용 되는게 다 다르겠지만, 나는 옵저버스 리스트 안에있는 모든 옵저버들에게 내 인풋필드에 적은 텍스트를 넘겨줬다.
public class Slave : MonoBehaviour, IObserver
{
public King myKing;
public Text myText;
public void OnEnable()
{
myKing.AddObserver(this);
}
private void OnDisable()
{
myKing.RemoveObserver(this);
}
public void UpdateKingNoify(string notify)
{
myText.text = notify;
}
}
노예 클래스에서는 IObserver를 상속받았다.
1. 키고 꺼질때 옵저버리스트에 추가, 삭제 되도록 King 클래스에서 구현한 함수들을 써주었다.
2. 왕에게서 알림을 받는 UpdateKingNoify에서는 내 텍스트에 알림을 띄우게했다.
왕의 버튼에 NotifyToObserver() 함수를 넣어주고 테스트 해보았다.
부하들이 텍스트를 잘 띄우는 것을 볼 수 있다.
물론 내가 지금 구현한것은 한 클래스안에서 인풋필드와 텍스트 3개를 다 넣고 실행해도 큰 문제가 없는 기능이지만,
만약 각 클래스마다 흩어져있는 곳에 이 객체의 변화에 대해 알려줘야 한다면 너무나도 유용할거라고 생각한다.
예를들면 몬스터에게 맞아서 변화된 HP를 화면에 띄워놓은 HP UI와 캐릭터 정보창에 모두 변경을 시켜줘야 한다면?
수많은 데이터들의 변화를 여러곳에 적용을 시켜줘야 한다면?
하드 코딩으로 따로따로 다 구현할수도 있는거지만 이런 유용한 패턴들을 작업량을 줄여주고 성능을 올려주는 것 같다.
'프로그래밍 공부 > 자료구조&알고리즘 공부' 카테고리의 다른 글
버블 정렬 알고리즘 (0) | 2022.07.17 |
---|---|
재귀 알고리즘 / 순차곱셈 구하기, 유클리드 호제법 구현 (0) | 2022.07.16 |
시간 복잡도와 함수 포인터 (0) | 2022.07.09 |
이진 검색 알고리즘(Binary Search) (0) | 2022.07.08 |
선형 검색 & 순차 검색 (0) | 2022.07.06 |
포스팅이 좋았다면 "좋아요❤️" 또는 "구독👍🏻" 해주세요!