Observer 1. Observer

Observer 1. Observer

코드들은 설명을 위한 예제 코드입니다. 오류가 있을 수 있습니다.

옵저버 패턴은 객체 간의 일대다(1:N) 관계를 정의하여, 하나의 객체(Observable)에서 발생하는 상태 변화가 여러 Observer(옵저버) 객체들에게 전달되도록 하는 디자인 패턴입니다. 이 패턴은 상태 변화와 그에 따른 반응을 명확하게 분리함으로써 객체 간의 결합도를 낮추고, 시스템을 더 유연하고 확장 가능하게 만듭니다.

코드 스멜

옵저버 패턴은 아래와 같은 코드 스멜을 해결하는 데 특히 효과적입니다:

  1. God Object: 하나의 객체가 너무 많은 책임을 지고 상태 변화와 그에 따른 작업을 모두 처리하는 경우 발생합니다. 옵저버 패턴은 상태 변화에 대한 책임을 다른 객체(옵저버)로 분산시킴으로써 책임의 분리를 돕습니다.

  2. Shotgun Surgery: 하나의 변경 사항이 여러 클래스나 모듈에 퍼지면서, 하나의 상태 변화가 여러 곳에서 수동으로 처리되어야 하는 문제를 말합니다. 옵저버 패턴은 상태 변화가 일어나면 자동으로 여러 옵저버에게 전달되므로, 여러 곳을 수동으로 수정할 필요가 없어집니다.

기본적인 옵저버 패턴 코드

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
public interface IObserver
{
    void Update();
}

public class Observer : IObserver
{
    public void Update()
    {
        // 상태 변화에 따른 프로세스
    }
}

public class Observable
{
    List<IObserver> observers = new();

    public void AddObserver(IObserver observer)
    {
        observers.Add(observer);
    }

    public void RemoveObserver(IObserver observer)
    {
        observers.Remove(observer);
    }

    public void Notify()
    {
        foreach (var observer in observers)
        {
            observer.Update(); // 각 옵저버의 콜백 메서드 호출
        }
    }
}

위 코드에서 Observable은 상태 변화를 감지하고, 등록된 모든 Observer에게 알림을 전달합니다. 옵저버는 자신의 Update 메서드를 통해 해당 알림을 처리합니다.

리스너, 핸들러, 콜백

옵저버 패턴을 설명할 때 리스너(listener), 핸들러(handler), 콜백(callback) 같은 개념들이 혼용되며, 종종 혼란을 야기합니다. 하지만 이 개념들을 명확히 구분하면 옵저버 패턴을 이해하기가 훨씬 수월해집니다.

  1. Listener: 이벤트를 “듣고” 그에 반응하는 함수나 객체를 의미합니다. 주로 이벤트가 발생했을 때 호출되는 메서드입니다.
  2. Handler: 리스너와 비슷한 개념으로, 이벤트를 처리하는 메서드입니다. 리스너와 핸들러는 거의 동일한 개념으로 사용할 수 있습니다.
  3. Callback: 특정 작업이 완료되면 호출되는 함수를 의미합니다.

옵저버 패턴에서의 해석

옵저버 패턴에서 ObservableNotify 메서드나 옵저버의 ‘Update’ 메서드 모두 보는 방법에 따라 다를 수 있습니다. 모두 Observable의 상태변화에 반응하는 리스너의 역할을 한다고 볼 수도 있습니다. 하지만 이를 좀 더 세밀하게 분류해보자면, ObservableNotify 메서드만 리스너의 역할을 한다고 하는게 좋습니다. 상태 변화에 반응하여 다른 여러 옵저버에게 변화를 전달하는 역할을 하기 때문입니다. 이에 따라 옵저버의 메서드는 리스너에 의해 호출되는 콜백으로 보면 구현할 때 헷갈리지 않을 수 있습니다.

SWeetJelly
SWeetJelly Programmer, Game Designer
comments powered by Disqus