CS/DesignPattern

[DesignPattern] 옵저버 패턴

리네엔 2024. 10. 14. 22:52

Observer Pattern이란?

  • 객체의 변화를 캐치하고, 그 객체에 의존하는 다른 객체들이 자동으로 알림을 받고 업데이트 될 수 있도록 하는 방법
  • 일대다 의존성을 갖게됨
  • 이벤트 기반 시스템이나 GUI 응용 프로그램에서 많이 사용됨
  • C#에서는 아예 event키워드로 지원함

Observer Pattern 구조

  • Subject : 상태를 관리하고, 옵저버들을 등록하거나 삭제할 수 있는 객체. 상태가 변하면 모든 옵저버들에게 변경사항을 통지
  • Observer : 주제의 상태를 관찰하는 객체.
public class Player{
    private List<IObserver> observers = new List<IObserver>();
    private int health;

    public int Health{
        get{return health;}
        set{
            health=value;
            NotyfiyObservers();
        }
    }
    public void Attach(IObserver observer){
        observers.Add(observer);
    }
    public void Detach(IObserver observer){
        observers.Remove(observer);
    }
    public void NotifyObservers(){
        foreach(var observer in observers){
            observers.Handle(Health);
        }
    }
}
public interface IObserver{
    void Update(int health);
}
public class HealthUI : IObserver{
    public void Handle(int health){
        Console.WireteLine($"{health}")
    }
}
public class Player
{
    public event Action OnDeathEvent;

    private int _health;
    public int Health
    {
        get {return _health;}
        set
        {
            _health=value;
            if(_health<0){OnDeathEvent();}
        }
    }
}

문제점들

  • 遅い. 느려.

    • 정적 호출 보다는 조금 느리겠지만, 크게 눈에 띄게 문제가 될 정도로 느리지 않다.
    • 그것보다 관찰자 패턴이 동기적이라는게 더 무서운점. 메서드중 하나가 느리면 블록될 수 있다.
    • 멀티스레드를 사용하면 락을 조심해야한다. 교착 상태에 빠지면..
  • 대상 혹은 옵저버가 저게 될때

    • 옵저버중 하나가 제거된지 모르고 알람을 보낸다면..
    • 대상이 죽었는지도 모르고 옵저버가 기다린다면..
      • 사망 메세지를 보내면 된다!
    • 사라진 리스너 문제
      • UI를 닫을 때 관찰자 등록을 취소하지 않는다면..

관찰자 패턴은 서로 연관 없는 코드 덩어리들이 하나의 큰 덩어리가 되지 않으면서 서로 상호작용하기에 좋은 방법이지, 하나의 기능을 구현하기 위한 코드 덩어리 안에서는 그다지 유용하지 않다.

장단점

장점

  • subject와 observer가 서로 독립적으로 존재할 수 있어 느슨한 결합을 유지할 수 있음.
  • 확장성 새로운 옵저버를 쉽게 추가할 수 있음 (OCP)
  • 주제의 상태가 변경될 때 모든 옵저버가 자동으로 업데이트 되어 수동 객체간의 상태를 동기화하는 작업을 줄일 수 있음. 이벤트 기반 시스템에서 효율적인 이벤트 처리가 가능함

단점

  • 디버깅이 어려움
  • 옵저버가 너무 많을 경우 시간이 오래걸릴 수 있음.
  • 등록만하고 해제하지 않는 다면 불필요한 옵저버가 할당되어 메모리 누수의 위험성이 있음
  • observer를 멀티스레드, 락과 함께 사용할때는 조심해야함. 락을 물고 있으면 게임이 교착 상태에 빠질 수 있음.

'CS > DesignPattern' 카테고리의 다른 글

[DesignPattern] 경량 패턴  (0) 2024.10.14
[DesignPattern] 커맨드 패턴  (0) 2024.10.14
[DesignPattern] 전략 패턴  (0) 2024.10.14
[DesignPattern] 싱글톤 패턴  (0) 2024.10.14
[Design Pattern]상태 패턴  (0) 2024.10.14