본문 바로가기
STUDY/디자인패턴

Observer 옵저버 패턴 ★★★

by 램플릿 2024. 7. 19.

내가 상태가 바뀌었을 때 이를 알아야 할 객체들에게 내 상태를 뿌려준다.

옵저버 패턴으로 Action이나 델리게이트를 조금 더 명확하게 만들었다고 할 수 있다.

라이브러리 사용은 생산성을 높여주지만 라이브러리에 대한 코드 장악력이 없으면 리스크가 발생할 수 있다.

그런데 옵저버 패턴은 델리게이트보다 내부 코드를 관리하기 용이하기 때문에 코드장악력이 높아진다.

때문에 옵저버안에 델리게이트를 넣어서 사용하기도 한다.

옵저버 패턴은 서버 만들 때 많이 사용한다.

 

 

using System.Collections.Generic;
using UnityEngine;

// 옵저버 인터페이스
public interface IObserver
{
    void OnNotify(string message);
}

// 주체(Subject) 클래스
public class Subject : MonoBehaviour
{
    private List<IObserver> observers = new List<IObserver>();
    
    // 옵저버 등록
    public void AddObserver(IObserver observer)
    {
        observers.Add(observer);
    }

    // 옵저버 제거
    public void RemoveObserver(IObserver observer)
    {
        observers.Remove(observer);
    }

    // 모든 옵저버에게 알림
    protected void NotifyObservers(string message)
    {
        foreach (var observer in observers)
        {
            observer.OnNotify(message);
        }
    }
}

// 구체적인 주체 클래스 예시 (플레이어)
public class Player : Subject
{
    private int health = 100;

    public void TakeDamage(int damage)
    {
        health -= damage;
        NotifyObservers($"Player health changed to {health}");

        if (health <= 0)
        {
            NotifyObservers("Player died");
        }
    }
}

// 구체적인 옵저버 클래스 예시 (UI)
public class HealthUI : MonoBehaviour, IObserver
{
    public void OnNotify(string message)
    {
        Debug.Log($"HealthUI received: {message}");
        // 여기서 UI를 업데이트합니다.
    }
}


// 구체적인 옵저버 클래스 예시 (UI)
public class PartyMemberNotify : MonoBehaviour, IObserver
{
    public void OnNotify(string message)
    {
        Debug.Log($"HealthUI received: {message}");
        // 여기서 UI를 업데이트합니다.
    }
}

// 사용 예시
public class ObserverExample : MonoBehaviour
{
    private Player _player;

    void Start()
    {
        _player = gameObject.AddComponent<Player>();
        HealthUI healthUI = gameObject.AddComponent<HealthUI>();
        PartyMemberNotify partyMemberNotify = gameObject.AddComponent<PartyMemberNotify>();

        _player.AddObserver(healthUI);
        _player.AddObserver(partyMemberNotify);

    }

    void Update()
    {
        if (Input.GetKeyDown(KeyCode.A))
        {
            // 플레이어가 데미지를 받으면 모든 옵저버에게 알림이 갑니다.
            _player.TakeDamage(20);
        }
    }
}

 

 

 

'STUDY > 디자인패턴' 카테고리의 다른 글

Memento 메멘토 패턴 ★  (0) 2024.07.19
Strategy 전략 패턴  (0) 2024.07.19
FSM(Finite-State-Machine) ★★★  (0) 2024.07.17
Command 커맨드 패턴 ★★★  (0) 2024.07.16
chain of responsibility 책임연쇄 패턴  (0) 2024.07.16