[UNITY],[C#]/TIL : UNITY

[디자인패턴] 이벤트 버스 패턴

네,가능합니다 2024. 10. 30. 20:13

요즘 TIL이 디자인패턴 투성이이다.. 최근 특강이 대부분 디자인 패턴에 관한 특강이기 때문이다.

너무 좋은 것 같다. 

하지만 이해는 잘 안 된다. 배우는 것과 내 것으로 만드는 건 아주 다른 거 기 때문에 자연스러운 걸 지도..?

그러면 지금부터 내 것으로 만드는 과정을 살펴보자

 

이벤트 버스 패턴이란 ?

이전에 정리했던 옵저버 패턴을 생각해보자

 

옵저버패턴은 이벤트를 등록 > 이벤트를 구독 > 이벤트가 발생하면 > 이벤트를 구독하는 메서드를 호출

 

이런방식이다 이때 "이벤트가 발생하면" 부분의 발생시키는 원인을 발행자 라고 생각하고 아래의 글을 보자

 

이벤트 버스 패턴은 아래와 같이 작동한다.

 

다수의 발행자 > 이벤트 버스 > 여러 구독자

 

옵저버 패턴과 유사하지만, 이벤트를 관리하는 이벤트 버스가 있기 때문에 관리가 더욱 쉬워지고

똑같은 이벤트의 발행자가 여러곳일 수 있는것이다.

 

이제 예제를 보며 학습해보자.

 

튜터님께서도 말씀하셨듯이 해당 패턴은 퀘스트시스템을 만드는데 매우 유용하다

 

딕셔너리를 활용하여 이벤트 버스 패턴을 사용한 예제를 보고 공부를 했었고, 예제들을 찾아보면 보통 그렇게 만들어져있는데,

 

이벤트 버스 패턴의 틀이 딕셔너리를 무조건 사용해야한다 ! 는 아니어서 딕셔너리 없이 적용해보도록 하겠습니다.

 

첫번째로 이벤트를 관리할 버스를 만들어줍니다.

 

public static class EventBus
{
    public static event Action EnemyDefeated;
    
    public static void PublishEnemyDefeated()
    {
        EnemyDefeated?.Invoke();
    }
}

EventBus클래스를 만들고 PublishEnemyDefeated 메서드에 이벤트를 등록해줍니다.

( PublishEnemyDefeated 메서드가 호출되면 EnemyDefeated 이벤트가 발동됨)

 

다음으로 해당 이벤트를 구독시키겠습니다.(구독자)

public class QuestTracker : MonoBehaviour
{
	public TextMeshProUGUI eventText;

    private void OnEnable() => EventBus.EnemyDefeated += UpdateQuestProgress;
    private void OnDisable() => EventBus.EnemyDefeated -= UpdateQuestProgress;

    private void UpdateQuestProgress()
    {
        eventText.text = "퀘스트 알림 : 몬스터가 처치되었습니다 !";
    }
}

 

다음으로 PublishEnemyDefeated를 발동시켜봅시다.(발행자)

public class Enemy : MonoBehaviour
{
    private void OnDeath()
    {
        EventBus.PublishEnemyDefeated();
    }
}

 

 

이 상태에서 적이 죽으면 어떻게 될까요 ?

적이 죽었을때 OnDeath()가 발동된다고 생각해봅시다.

 

OnDeath가 이벤트버스의 PublishEnemyDefeated()를 호출하고 해당 메서드안에 있는 이벤트가 발동되며,

해당 이벤트를 구독하고 있는 UpdateQuestProgress 가 호출되며, 플레이어에게 몬스터를 처치했다는 알림이 갑니다.

 

여기서 발행자가 만약 추가된다면

다른 클래스에서도 EventBus.PublishEnemyDefeated();를 호출하여, 손쉽게 이벤트를 발동시킬 수 있습니다.

 

이런 다양한 이벤트 패턴의 구조를 이해하고 적절하게 사용할줄 아는 사람이 된다면 좋겠다