자바 디자인 패턴 용어 사전
행위 패턴옵서버 · 발행/구독 · 리스너

Observer

상태 변화를 구독자들에게 알리는 패턴. 발행자가 구독자를 몰라도 되게 만든다.

한 객체의 상태가 바뀌면 그것에 의존하는 객체들에게 자동으로 알리는 패턴.

interface Observer { void update(Event e); }

class Subject {
    private final List<Observer> observers = new ArrayList<>();
    void subscribe(Observer o) { observers.add(o); }
    void unsubscribe(Observer o) { observers.remove(o); }

    protected void notifyAll(Event e) {
        for (Observer o : observers) o.update(e);   // 누가 듣는지 모른 채 알린다
    }
}

무엇을 얻나

발행자가 구독자를 몰라도 된다

  • 구독자를 추가·제거해도 발행자 코드가 안 바뀐다 (OCP)
  • 결합이 끊긴다

어디에 있나

  • UI 이벤트 리스너

  • 반응형 스트림 (구독하면 값이 흐른다)

  • 메시지 발행/구독

  • 프레임워크의 애플리케이션 이벤트

  • MVC 의 모델 → 뷰 갱신

  • "리스너" · "콜백" · "구독" 이라는 말이 붙으면 대개 이 패턴이다

실무에서 데는 곳

  • ① 구독 해제를 잊는다

    • 발행자가 구독자 참조를 계속 들고 있어 메모리 누수
    • 화면이 사라져도 리스너가 남는 것이 대표적
    • 약한 참조를 쓰거나, 생명주기에 맞춰 자동 해제되게 만든다
  • ② 순회 중 구독 해제

    • notifyAll 도중에 목록이 바뀌면 ConcurrentModificationException
    • 복사본을 순회하거나 CopyOnWriteArrayList 를 쓴다
  • ③ 통지가 연쇄된다

    • A 알림 → B 가 상태를 바꿈 → 또 알림 → ... 무한 루프
    • 순환을 만들지 않도록 설계하거나 재진입을 막는다
  • ④ 순서에 의존한다

    • 구독 순서에 따라 결과가 달라지면 깨지기 쉽다

push와 pull

  • push — 알릴 때 데이터를 함께 넘긴다 — 간단하지만 필요 없는 데이터도 보낸다
  • pull — "바뀌었다" 만 알리고 구독자가 필요한 것을 가져간다 — 유연하지만 왕복이 는다

동기와 비동기

  • 동기 통지 — 발행자 스레드에서 구독자가 실행된다
    • 구독자 하나가 느리면 발행자가 막힌다

    • 예외가 나면 발행자까지 영향을 받는다 비동기 통지 큐를 두고 다른 스레드에서 처리한다

    • 격리되지만 순서·유실을 신경 써야 한다

면접 함정

  • "Observer는 항상 비동기" → 기본은 동기 호출이다.
  • "구독만 하면 끝" → 해제를 잊으면 누수다. 이게 실무 버그의 대부분이다.

이벤트 버스로 확장되면

Observer 를 전역화한 형태가 이벤트 버스다

  • 장점 — 발행자와 구독자가 서로를 전혀 모른다
  • 단점 — '누가 이 이벤트를 듣는지' 를 코드에서 추적할 수 없다
    • 흐름이 사라진다. 디버깅이 어려워진다

경계: 모듈 안에서는 직접 호출, 모듈 경계에서만 이벤트

순서 보장이 필요하면

// 구독자에 우선순위를 준다
observers.sort(Comparator.comparingInt(Observer::order));

// 다만 순서에 의존하는 설계 자체가 냄새다
// → 순서가 중요하면 명시적 호출이나 파이프라인이 낫다

예외 처리 전략

for (Observer o : new ArrayList<>(observers)) {   // 복사본을 순회한다
    try { o.update(e); }
    catch (Exception ex) { log.error("구독자 실패", ex); }   // 하나가 실패해도 계속
}

구독자 하나의 실패가 나머지를 막지 않게 하는 것이 실무의 기본이다 — 다만 실패를 삼키기만 하면 조용히 동작이 빠지므로 반드시 로그를 남긴다.

함께 보면 좋은 용어

노트에서 맥락과 함께 보기 — 행위 패턴 ② — 돌고, 알리고, 되돌린다