Search

이벤트 버스 패턴

class
디자인 패턴
상태
완료
날짜
목차

이벤트 버스 패턴

이벤트 버스 패턴은 게시자가 구독자에게 신호를 보내는 패턴입니다.
이벤트 버스 패턴은 가장 간단하게, 전역 이벤트 프로토타입에서 가장 많이 사용하는 패턴입니다.
델리게이트의 기본적인 이해와 프로토타입 테스트를 위해서는 꼭 알아야하는 패턴이기도 합니다.

이벤트 버스의 게시자와 구독자

이벤트 버스에서 게시자와 구독자는 다음과 같은 역할을 갖고 있습니다.
게시자(EventPublihser) : 이벤트 버스에서 선언한 특정 종류의 이벤트를 구독자에게 게시할 수 있습니다.
이벤트 버스(EventBus) : 이벤트 버스는 구독자와 게시자 사이의 이벤트 전송을 고정하는 역할을 합니다.
구독자(EventSubscriber) : 이벤트 버스를 통해 특정 이벤트의 구독자로 자신을 등록합니다.

이벤트 버스의 사용

빠른 프로토타이핑 : 이벤트 버스는 주로 프로토타입에서 사용합니다. ㄴ 예를 들어 어떤 객체들이 원하는 시점에 행동을 하고 싶을 때, 이벤트 버스를 사용한다면 손쉽게 구현할 수 있습니다.
프로덕션 코드 : 게임에서 이벤트 코드를 정교하게 관리하지 않아도 된다면, 사용할 수 있습니다. 다만, 이 부분은 대부분의 게임에 해당되지 않습니다.

이벤트 버스의 장단점

장점
1.
분리 : 이벤트 시스템을 사용할 때, 주요 이점은 오브젝트를 분리 한다는 점입니다. 오브젝트는 직접 서로를 참조하는 대신 이벤트로 통신할 수 있습니다. ㄴ 오브젝트가 서로 연결되어 있지 않고 오직, 이벤트 버스로만 대화를 주고 받는 것입니다. ㄴ MMORPG의 스킬 사용 행동 로직과 비슷합니다. 실제로 유저가 스킬을 사용할 때, 스킬 사용을 서버에게 알리고 서버는 해당 유저가 스킬을 사용했다는 것을 다시 유저들에게 알려줍니다. 이 때, 유저는 서버에게 알림을 받았을 때, 스킬을 사용하죠.
2.
단순성 : 이벤트 버스는 이벤트 구독 혹은 게시 매커니즘을 추상화하여, 단순성을 제공한다. ㄴ 이건 이벤트 버스마다 다르겠지만, Action과 Event 등 함수를 직접적으로 넣어줌으로써 이벤트를 단순 발동 시킨다는 것을 의미합니다. ㄴ 이벤트 버스만이 가지고 있는 특성은 아니지만, 이벤트 버스가 보통 프로토타입에서 많이 사용한다는 점에서 이러한 이점을 보통 갖고 있습니다.
단점
1.
성능 : 모든 이벤트 시스템은 오브젝트 간 메시지를 관리하는 저수준 매커니즘이 있습니다. 플랫폼에 따라 다르겠지만, 약간의 성능 비용이 발생할 수 있습니다.

레이스 이벤트 버스 구현하기

레이스 이벤트 버스

이벤트들을 관리할 이벤트 버스입니다.
public enum RaceEventType { COUNTDOWN, } public class RaceEventBus { private static readonly IDictionary<RaceEventType, UnityEvent> Events = new Dictionary<RaceEventType, UnityEvent>(); public static void Subscribe(RaceEventType eventType, UnityAction listener) { UnityEvent thisEvent; if (Events.TryGetValue(eventType, out thisEvent)) { thisEvent.AddListener(listener); } else { thisEvent = new UnityEvent(); thisEvent.AddListener(listener); Events.Add(eventType, thisEvent); } } public static void Unsubscribe(RaceEventType type, UnityAction listener) { UnityEvent thisEvent; if (Events.TryGetValue(type, out thisEvent)) { thisEvent.RemoveListener(listener); } } public static void Publish(RaceEventType type) { UnityEvent thisEvent; if (Events.TryGetValue(type, out thisEvent)) { thisEvent.Invoke(); } } }
C#
복사
레이스 이벤트는 타입에 따라 이벤트를 관리합니다.
Events : 이벤트들이 저장되는 변수입니다.
Subscribe : 이벤트들을 위 Events 변수에 저장하는 함수입니다.
기존에 같은 타입의 이벤트가 등록되어있을 때는, 해당 이벤트에 추가로 등록할 Action을 담습니다.
기존에 같은 타입의 이벤트가 등록되어 있지 않을 경우, Event를 인스턴스화 후, 등록할 Action을 담습니다.
Unsubscribe : 해당 Type에 등록되어있는 Action을 삭제합니다.
Publish : 해당 Type에 등록되어있는 모든 Action을 발동합니다.

카운트 다운 타이머

이벤트 버스에 카운트 다운과 관련된 함수들을 등록합니다.
public class CountdownTimer : MonoBehaviour { void OnEnable() { RaceEventBus.Subscribe(RaceEventType.COUNTDOWN, StartTimer); } void OnDisable() { RaceEventBus.Unsubscribe(RaceEventType.COUNTDOWN, StartTimer); } private void StartTimer() { // 타이머 시작 코드~ } }
C#
복사
가장 중요한 부분은, 이벤트 버스에 자신의 함수들을 등록하는 부분입니다.
이로써 CountDownTimer는 구독자로써 이벤트 버스에 COUNTDOWN이 발동될 때, StartTimer라는 함수가 발동되게 구독하는 것입니다.

이벤트 버스의 대안

이벤트라는 것은 어떤 시스템을 구현 하냐에 다라 많은 방식이 있습니다.
옵저버 패턴, 이벤트 큐, 유니티의 ScriptableObject의 이벤트 시스템 등등 수 많은 이벤트 시스템이 존재합니다.
중요한 점은 이벤트 시스템과 매커니즘을 구현할 때, 고려해야 하는 부분이 무엇인지를 확실하게 파악하고 그 것에 맞춰 구현해야 합니다.

PS. 스크립터블 오브젝트 이벤트 시스템

이벤트라는 것은 많은 방식이 있습니다.
스크립터블 오브젝트는 이벤트 버스에 등록됨으로써 어떤 이벤트가 발생할 때, 해당 스크립터블 오브젝트가 실행되는 것이죠.
(기본적으로 비슷한 로직이지만, 여기서 설명한 완전한 이벤트 버스는 아닙니다.)
예를 들어, 아래와 같이 동작합니다.
1.
플레이가이드 이벤트 버스에 상태와 동작 Action을 담습니다.
2.
여기서 상태는 기존과 비슷하지만 동작 Action 스크립터블 오브젝트를 직접적으로 담을 수 있습니다.
3.
다음으로 플레이가이드에서 조건에 따라 스크립터블 오브젝트들을 실행합니다.
조금 다른 점은 Action이 아닌 스크립터블 오브젝트르 담음으로써 오직 발동되는 것이 아니라, 담긴 스크립터블 오브젝트의 함수에 따라 원하는 함수를 발동할 수 있다는 것입니다.