Programming/디자인패턴

옵저버 패턴(Observer Pattern), 왜 이렇게 많이 쓰일까?! 👀

철부지개발자 2025. 3. 7. 08:16
반응형

변화에 즉각 반응하는 패턴! 옵저버 패턴 쉽게 이해하기

프로그래밍을 하다 보면 "이벤트 발생 시 즉시 반응해야 하는 경우"가 진짜 많아요!
예를 들어, 유튜브에서 "구독" 버튼을 누르면 어떻게 되죠?

  • 내 유튜브 피드에 새로운 영상이 뜨고
  • 구독 채널에 알람이 가고
  • 내 활동 로그에도 기록되고

이 모든 과정이 한 번의 "구독" 액션으로 동시에 이루어진다구요.
이런 걸 가능하게 해주는 게 바로 옵저버 패턴(Observer Pattern)! 🎯

근데 이게 도대체 뭔데?
어떻게 동작하는데?
어렵지 않게, 예제 코드까지 곁들여서 쉽게 설명해보겠습니다!

1. 옵저버 패턴이란? 🧐

옵저버 패턴은 "어떤 객체의 상태가 변경되었을 때, 그 변화를 여러 객체가 감지하고 반응할 수 있도록 하는 디자인 패턴"입니다.

쉽게 말해, "감시자(Observer)"가 "관찰 대상(Subject)"을 지켜보다가,
어떤 변화가 생기면 즉시 반응하는 구조라고 보면 되는거죠!

이게 어디에 쓰이냐구요?
대표적으로 이런 곳에서 사용됩니다!

  • 이벤트 시스템 (버튼 클릭, 키 입력 감지 등)
  • 알림 시스템 (SNS, 유튜브 구독 알림 등)
  • MVC 패턴에서 View 업데이트

즉, "내가 뭔가 바뀌었어!"라고 신호를 주면,
여러 개의 옵저버들이 "오! 변경됐네?" 하면서 자기 할 일을 하는 구조인 거죠.


2. 옵저버 패턴을 코드로 보면? 👨‍💻

말보단 코드가 낫겠쥬?
자바(Python도 거의 비슷함!)로 옵저버 패턴을 구현해봅시다!

// 1. 관찰 대상(Subject) 인터페이스
interface Subject {
    void addObserver(Observer o);
    void removeObserver(Observer o);
    void notifyObservers();
}

// 2. 옵저버(Observer) 인터페이스
interface Observer {
    void update(String message);
}

// 3. 실제 Subject 구현 (유튜브 채널)
class YouTubeChannel implements Subject {
    private List<Observer> observers = new ArrayList<>();
    private String videoTitle;

    public void uploadVideo(String title) {
        this.videoTitle = title;
        notifyObservers(); // 모든 구독자에게 알림 보냄!
    }

    @Override
    public void addObserver(Observer o) {
        observers.add(o);
    }

    @Override
    public void removeObserver(Observer o) {
        observers.remove(o);
    }

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

// 4. 옵저버(구독자)
class Subscriber implements Observer {
    private String name;

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

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

// 실행 예제
public class ObserverPatternDemo {
    public static void main(String[] args) {
        YouTubeChannel channel = new YouTubeChannel();

        Subscriber s1 = new Subscriber("철수");
        Subscriber s2 = new Subscriber("영희");

        channel.addObserver(s1);
        channel.addObserver(s2);

        channel.uploadVideo("옵저버 패턴 강의"); // 모든 구독자에게 알림 전송!
    }
}

3. 코드 해석 🧐

이제 코드 하나씩 뜯어볼까요?
  • Subject (관찰 대상): addObserver, removeObserver, notifyObservers 3가지 핵심 메서드를 가짐
  • Observer (옵저버): update(String message) 메서드만 구현하면 됨!
  • YouTubeChannel: 구독자 목록을 관리하며, 새 영상이 업로드되면 구독자들에게 알림을 보냄
  • Subscriber: 구독자로서 update()가 호출될 때 알림을 받음
    즉, channel.uploadVideo("옵저버 패턴 강의")를 실행하면
    모든 구독자들이 "새 영상이 업로드되었어요!"라는 메시지를 받게 되는 거쥬!

4. 옵저버 패턴의 장점 💡

그럼 이걸 왜 쓸까요?

✅ 느슨한 결합 (Loose Coupling)

YouTubeChannel과 Subscriber가 서로 직접 연결되지 않음
즉, Subscriber를 추가하거나 삭제해도 YouTubeChannel을 수정할 필요 없음
✅ 확장성이 좋음

새로운 옵저버를 추가하는 게 쉽다!
예를 들어, Subscriber 말고도 EmailNotifier, SMSNotifier 같은 옵저버를 추가하면
유튜브 영상 알림을 이메일로도 받을 수 있고, 문자로도 받을 수 있음
✅ 자동 업데이트

수동으로 "야, 영상 올라왔어!"라고 알려줄 필요 없이
새로운 컨텐츠가 등록되면 자동으로 업데이트 됨!


5. 옵저버 패턴의 단점 ⚠️

하지만 단점도 있슴다!  
❌ 옵저버가 많아지면 성능 문제 발생

옵저버가 10명, 100명, 1000명이 되면?
notifyObservers() 호출이 많아지면서 성능이 저하될 수 있음!
❌ 예측하기 어려운 실행 순서

옵저버들이 비동기적으로 실행될 경우,
"어떤 옵저버가 먼저 실행될지" 보장이 안 됨!
따라서 중요한 순서가 필요한 경우 사용에 주의해야 함


6. 언제 옵저버 패턴을 써야 할까? 🤔

옵저버 패턴을 써야 할 때는?  
✅ 상태 변화가 있을 때, 여러 개의 객체가 그 변화를 알아야 하는 경우  
✅ 이벤트 기반 시스템 (버튼 클릭, 키 입력 등)  
✅ 실시간 알림 시스템 (유튜브, 인스타그램, 이메일 알림)  
✅ 게임에서 캐릭터가 변할 때 UI가 자동 업데이트 되어야 하는 경우

즉, "하나의 변화가 여러 객체에 영향을 줄 때" 옵저버 패턴이 딱 맞는 패턴입니다!


💡 옵저버 패턴, 자주 묻는 질문들

🔹 옵저버 패턴을 MVC 패턴에서 어떻게 활용할 수 있나요?

👉 보통 ModelView들에게 변경 사항을 알려줄 때 옵저버 패턴이 사용됨!
즉, 데이터가 바뀌면 UI가 자동으로 갱신될 수 있음

🔹 옵저버 패턴 vs 이벤트 리스너, 차이점은?

👉 이벤트 리스너는 특정한 이벤트에만 반응하지만,
옵저버 패턴은 "상태 변화"에 대한 반응을 관리하는 패턴임

🔹 옵저버 패턴의 대안은?

👉 메시지 큐(MQ)나 리액티브 프로그래밍 (RxJava, RxJS) 같은 방법이 있음!


🚀 여러분은 옵저버 패턴을 어디서 써보셨나요?

댓글로 의견 남겨주시면 같이 이야기해봐요! 😊

반응형