#14 Observer Pattern

Yumin·2025년 1월 27일

Computer Science

목록 보기
14/17

옵저버 패턴
옵저버 패턴(Observer Pattern)은 정말 널리 쓰이는 디자인 패턴 중 하나. 주체(Subject)와 옵저버(Observer)가 상호작용하면서 상태 변화를 전달하는 방식은 특히 이벤트 중심의 시스템에서 효과적. 트위터나 소셜 네트워크의 로직처럼 실시간 업데이트가 필요한 상황에서 딱 들어맞음..

예를 들어, 트위터에서는:

주체(Subject): 특정 사용자가 게시글을 작성하거나 프로필을 업데이트할 때.
옵저버(Observer): 팔로워들이 주체의 게시글이나 업데이트를 바로 볼 수 있도록 알림을 받는 구조.
MVC 패턴에서도:

View(옵저버)Model(주체)를 관찰하다가, 데이터가 바뀌면 이를 반영해 화면을 갱신하는 방식으로 동작.
실제로 유니티에서도 이벤트 기반 구조를 구현할 때 옵저버 패턴을 적용할 수 있음. 예를 들면, 게임 내 점수나 체력 변화를 여러 UI 요소에 동기화시킬 때 사용 가능.

주체(Subject): HealthManager


using System;
using System.Collections.Generic;
using UnityEngine;

public class HealthManager : MonoBehaviour
{
    public int Health { get; private set; } = 100; // 초기 체력
    private List<IHealthObserver> observers = new List<IHealthObserver>();

    public void RegisterObserver(IHealthObserver observer)
    {
        if (!observers.Contains(observer))
            observers.Add(observer);
    }

    public void UnregisterObserver(IHealthObserver observer)
    {
        if (observers.Contains(observer))
            observers.Remove(observer);
    }

    public void TakeDamage(int damage)
    {
        Health = Mathf.Max(Health - damage, 0);
        NotifyObservers();
    }

    private void NotifyObservers()
    {
        foreach (var observer in observers)
        {
            observer.OnHealthChanged(Health);
        }
    }
}
// UNITY EVENT로 제작 시
using UnityEngine;
using UnityEngine.Events;

public class HealthManager : MonoBehaviour
{
    public UnityEvent<int> OnHealthChanged = new UnityEvent<int>();
    public int Health { get; private set; } = 100;

    public void TakeDamage(int damage)
    {
        Health = Mathf.Max(Health - damage, 0);
        OnHealthChanged.Invoke(Health); // 이벤트 호출
    }
}

옵저버(Observer) 인터페이스

public interface IHealthObserver
{
    void OnHealthChanged(int newHealth);
}

옵저버: HealthBar

using UnityEngine;
using UnityEngine.UI;

public class HealthBar : MonoBehaviour, IHealthObserver
{
    [SerializeField] private Slider healthSlider;

    private void Start()
    {
        // HealthManager를 찾아 등록
        HealthManager healthManager = FindObjectOfType<HealthManager>();
        if (healthManager != null)
        {
            healthManager.RegisterObserver(this);
        }
    }

    public void OnHealthChanged(int newHealth)
    {
        healthSlider.value = newHealth / 100f; // 슬라이더 값 업데이트
    }
}

// UNTIY EVENT로 제작시 

using UnityEngine;
using UnityEngine.UI;

public class HealthBar : MonoBehaviour
{
    [SerializeField] private Slider healthSlider;

    private void Start()
    {
        HealthManager healthManager = FindObjectOfType<HealthManager>();
        if (healthManager != null)
        {
            healthManager.OnHealthChanged.AddListener(UpdateHealthBar);
        }
    }

    private void UpdateHealthBar(int newHealth)
    {
        healthSlider.value = newHealth / 100f;
    }
}

옵저버: HealthText

using UnityEngine;
using UnityEngine.UI;

public class HealthText : MonoBehaviour, IHealthObserver
{
    [SerializeField] private Text healthText;

    private void Start()
    {
        HealthManager healthManager = FindObjectOfType<HealthManager>();
        if (healthManager != null)
        {
            healthManager.RegisterObserver(this);
        }
    }

    public void OnHealthChanged(int newHealth)
    {
        healthText.text = $"Health: {newHealth}";
    }
}

// UNITY EVENT로 제작시
using UnityEngine;
using UnityEngine.UI;

public class HealthText : MonoBehaviour
{
    [SerializeField] private Text healthText;

    private void Start()
    {
        HealthManager healthManager = FindObjectOfType<HealthManager>();
        if (healthManager != null)
        {
            healthManager.OnHealthChanged.AddListener(UpdateHealthText);
        }
    }

    private void UpdateHealthText(int newHealth)
    {
        healthText.text = $"Health: {newHealth}";
    }
}
  1. 게임에서의 사용
    HealthManager를 빈 게임오브젝트에 붙이고 초기 체력을 설정.
    HealthBar와 HealthText는 각각 UI 오브젝트에 연결.
    HealthManager의 TakeDamage(int damage) 메서드를 호출하면 체력이 줄어들고, 등록된 옵저버(UI 요소)들이 자동으로 업데이트.

    동작 흐름

    HealthManager가 상태를 관리하고 변화 시 옵저버들에게 알림을 보냄.
    옵저버들은 알림을 받아 UI를 업데이트.
profile
일본 게임회사에서 클라이언트 엔지니어로 활동중

0개의 댓글