🏆 목차.
🛒 서론
옵저버 패턴(Observer Pattern)
옵저버 패턴(Observer Pattern)은 하나의 객체 상태가 변경될 때 종속된 모든 객체들에게 자동으로 알리는 디자인 패턴입니다. 이 패턴은 이벤트 핸들링, 모델-뷰-컨트롤러(MVC) 구조, 실시간 데이터 스트리밍 등에서 많이 사용되며, 특히 게임 개발에 필수적인 디자인 패턴입니다. 이번 글에서 옵저버 패턴의 개념과 동작 방식에 대해 살펴보겠습니다.
🎨 본론
옵저버 패턴은 주체가 되는 객체(Subject)의 상태가 변경되면 해당 객체를 구독한 모든 객체들(Observer)에게 알려줍니다.
여기서 중요한 특징은 Subject는 Observer의 존재를 전혀 모른다는 점입니다.
그래서 수신한 Observer가 무엇을 하든 관여를 하지 않습니다.
이를 통해 1 : N 종속 관계를 사용하여 객체가 통신하되 낮은 결합도를 유지할 수 있습니다.
이는 SOLID 원칙을 잘 준수하는 패턴이라고 볼 수 있습니다.
옵저버 패턴 예시 코드)
인터페이스 IObserver, ISubject
public interface IObserver
{
void Update();
}
public interface ISubject
{
void Attach(IObserver observer);
void Detach(IObserver observer);
void Notify();
}
인터페이스를 상속받고 있는 Player클래스
public class Player : ISubject
{
private List<IObserver> observers = new List<IObserver>();
private int score;
public int Score
{
get { return score; }
set
{
score = value;
Notify();
}
}
public void Attach(IObserver observer)
{
observers.Add(observer);
}
public void Detach(IObserver observer)
{
observers.Remove(observer);
}
public void Notify()
{
foreach (IObserver observer in observers)
{
observer.Update();
}
}
}
Player 객체 상태 변화를 감지하고 UI를 업데이트하는 ScoreBoard 클래스
public class ScoreBoard : IObserver
{
private Player player;
public ScoreBoard(Player player)
{
this.player = player;
player.Attach(this);
}
public void Update()
{
Console.WriteLine("플레이어 점수는 : " + player.Score);
}
public void Unsubscribe()
{
player.Detach(this);
}
}
사용 예시
Player player = new Player();
ScoreBoard scoreBoard = new ScoreBoard(player);
// 플레이어의 점수 변경
player.Score = 10;
player.Score = 20;
코드 설명
IObserver
- 옵저버 클래스가 상속받을 인터페이스입니다.
- ' Update '함수를 이용해 Subject의 상태가 변경되었을 때 원하는 기능을 작동시킬 수 있습니다.
ISubject
- 옵저버의 구독 대상이 될 객체가 상속받을 인터페이스입니다.
- 구독, 구독 해제, 브로드캐스팅 기능을 하는 함수를 작성했습니다.
Player
- 점수 정보를 가지고 있는 객체로 ' ISubject '인터페이스를 상속받고 있습니다.
- ' Score '를 set할 때 ' Notify '를 호출해서 구독된 옵저버들의 ' Update '를 호출해줍니다.
ScoreBoard
- Player 객체를 구독할 객체로 ' IObserver '인터페이스를 상속받고 있습니다.
- 생성자를 통해 Player 객체를 구독 처리하고 점수가 변경될 때 작동할 기능을 ' Update '함수를 통해 구현할 수 있습니다.
UniRx를 활용한 옵저버 패턴
UniRx 라이브러리를 활용하면 옵저버 패턴을 더욱 간단하고 직관적으로 구현할 수 있습니다.
동일한 기능을 UniRx를 이용해 구현해 보겠습니다.
점수 정보를 가지고 있는 Player 클래스
using UniRx;
using UnityEngine;
public class Player : MonoBehaviour
{
public ReactiveProperty<int> score = new ReactiveProperty<int>();
}
점수 정보를 구독할 옵저버 ScoreBoard 클래스
using UniRx;
using UnityEngine;
public class ScoreBoard : MonoBehaviour
{
public Player player;
private void Start()
{
player.score.Subscribe(newScore =>
{
Debug.Log("점수가 변동됨 " + newScore);
});
}
}
코드 설명
Player
- ' int '형인 ' score '를 ' ReactiveProperty '로 선언하여 값이 변경될 때마다 자동으로 이벤트를 발생시켜 구독자에게 알리도록 했습니다.
ScoreBoard
- ' player '의 ' score '를 구독해서 값이 변동될 때 변동된 값이 출력되게 만들었습니다.
첫 번째 코드보다 UniRx를 사용했을 때 훨씬 더 코드가 간결해진 것을 볼 수 있습니다.
🎯 결론
옵저버 패턴은 상태 변화에 따라 여러 객체가 반응해야 하는 상황에서 유용한 디자인 패턴입니다. 이를 통해 객체 간의 결합도를 낮추고, 유지보수성을 높일 수 있습니다. UniRx를 활용하면 이러한 옵저버 패턴을 더욱 간결하고 직관적으로 구현할 수 있습니다. 게임 개발에서 상태 변화와 이벤트 핸들링을 효과적으로 관리하기 위해 옵저버 패턴을 적절히 활용하는 것이 중요합니다. UniRx는 이러한 작업을 더욱 쉽게 만들어주어 개발 효율성을 크게 향상할 수 있습니다.
'프로그래밍 > 디자인패턴' 카테고리의 다른 글
[디자인패턴] 상태 패턴(State Pattern) (0) | 2024.06.21 |
---|---|
[디자인패턴] 팩토리 패턴(Factory Pattern) (0) | 2024.06.14 |