본문 바로가기
LV3_Advanced/GOF 패턴

Observer (옵저버) - 행위 패턴 #3

by 하타라시 2026. 2. 26.

목차

💡
  • 왜 옵저버 패턴을 사용해야 하는가
  • 설계도는 어떻게 생겼나?
  • 실제로 어떻게 구현하나?
  • 장점과 단점은 무엇인가?

왜 옵저버 패턴을 사용해야 하는가?

옵저버 패턴은 어떤 객체의 상태가 변경되었을 때, 그 객체에 의존하는 다른 객체들에게 자동으로 알림을 보내기 위해 사용하는 패턴입니다.

즉, 하나의 객체의 변화가 여러 객체에 전파되어야 할 때 적합합니다.

예를 들어, 유튜브 채널과 구독자의 관계를 생각해볼 수 있습니다.

유튜버가 영상을 업로드하면, 해당 채널을 구독하고 있는 모든 구독자에게 알림이 전달됩니다.

※ 중간 브로커 없이 직접 참조가 이루어지는 것이 핵심입니다. ※

설계도는 어떻게 생겼나?

홍길동과 김철수는 한 유튜브 채널을 구독하고 있습니다.

이 상태에서 유튜버가 새로운 영상을 업로드하면, 구독 중인 두 사람 모두에게 알림이 전송됩니다.

이후 김철수가 구독을 취소하면, 다음 영상이 업로드될 때는 더 이상 김철수에게 알림이 전달되지 않습니다.

결과적으로, 구독을 유지하고 있는 홍길동에게만 알림이 전송됩니다.

실패

실제로 어떻게 구현하나?

인터페이스 설계

public interface Observer {
    void update(String videoTitle);
}

public interface Subject {
    void subscribe(Observer observer);
    void unsubscribe(Observer observer);
    void notifyObservers();
}

구체 클래스 구현

import java.util.ArrayList;
import java.util.List;

public class TechChannel implements Subject {

    private List<Observer> observers = new ArrayList<>();
    private String latestVideoTitle;

    @Override
    public void subscribe(Observer observer) {
        observers.add(observer);
    }

    @Override
    public void unsubscribe(Observer observer) {
        observers.remove(observer);
    }

    @Override
    public void notifyObservers() {
        for (Observer observer : observers) {
            observer.update(latestVideoTitle);
        }
    }

    public void uploadVideo(String title) {
        this.latestVideoTitle = title;
        System.out.println("\\n[채널 관리자] 새로운 영상 업로드: " + title);
        notifyObservers();
    }
}

public class User implements Observer {

    private String name;

    public User(String name) {
        this.name = name;
    }

    @Override
    public void update(String videoTitle) {
        System.out.println("🔔 " + name + "님, 새 영상이 업로드되었습니다: " + videoTitle);
    }
}

사용 예시

public class Main {

    public static void main(String[] args) {

        TechChannel techChannel = new TechChannel();

        User user1 = new User("홍길동");
        User user2 = new User("김철수");

        techChannel.subscribe(user1);
        techChannel.subscribe(user2);

        techChannel.uploadVideo("옵저버 패턴 이해하기");

        techChannel.unsubscribe(user2);

        techChannel.uploadVideo("실무에서 쓰이는 디자인 패턴");
    }
}

장점과 단점은 무엇인가?

장점

  • 느슨한 결합
    • Subject는 Observer의 구체적인 구현을 알 필요가 없습니다. 인터페이스를 통해 연결되므로 확장에 유리합니다.
  • 확장 용이
    • 새로운 Subject를 추가하더라도 기존 코드를 수정할 필요가 없습니다.

단점

  • 알림 전파 비용 증가
    • Observer가 많아질 수록 상태 변경 시 처리 비용이 증가합니다.
  • 디버깅 어려움
    • 상태 변화가 여러 객체로 전파되기 때문에 흐름 추적이 어려울 수 있습니다.