inblog logo
|
An's Blog
    JAVA

    [JAVA] 62. 옵저버 패턴 (관찰자 패턴)

    윤설안's avatar
    윤설안
    Jul 23, 2025
    [JAVA] 62. 옵저버 패턴 (관찰자 패턴)
    Contents
    🔴 Polling 방식1. 코드 예시 기반 설명2. Polling의 코드를 작성 할 시 주의할 점🟠 Push 방식1. 코드 예시 기반 설명2. Push의 특징과 장점3. Push 구현시 주의할 점🟡 두 방식 비교 정리

    옵저버 패턴(Observer Pattern)이란?

    "상태가 바뀌면, 알아서 알림 받는 구조"
    객체 간 1:N 관계를 정의하여, 하나의 객체 상태가 변경되면
    그 상태에 의존하는 다른 객체들에게 자동으로 알림이 가도록 한다.

    예시로 쉽게 이해하기

    고객 1 : "상품이 들어오면 알려줘!"
    마트 1 : "상품 들어오면 알려줄 테니 명단 적어줘"
    → 상품이 들어오면? → 고객 1에게 자동 알림이 전송됨
    이처럼 고객은 상태를 감지하지 않고,
    마트가 상태 변화를 감지해서 자동으로 알려주는 구조가 옵저버 패턴이다.

    🔴 Polling 방식

    Polling(폴링) 은 어떤 대상(서버, 객체, 장치 등)의 상태가 변경되었는지 계속 확인하는 방식이다.
    “변했니? 아직도 아니야? 지금은?”
    이렇게 계속 물어보는 구조를 의미한다.

    1. 코드 예시 기반 설명

    while (true) { Thread.sleep(100); // 잠깐 쉬고 if (lotteMart.getValue() != null) { customer1.update(lotteMart.getValue() + "가 들어왔습니다."); break; } else { System.out.println("아직 안 들어왔어요"); } }
    이 부분이 바로 Polling이다.
    0.1마다 lotteMart.getValue() 를 호출하면서 "상품 들어왔니?" 라고 계속 확인하고 있다.

    2. Polling의 코드를 작성 할 시 주의할 점

    1. Polling 주기 설정은 비즈니스와 성능의 균형이 중요

    • 짧게 설정하면 반응 속도는 빨라지지만 서버/CPU에 부하가 크다.
    • 길게 설정하면 부하는 적지만 사용자 체감 반응 속도가 느려질 수 있다.
    • ⇒ Thread.sleep() 또는 주기 설정 시 비즈니스 민감도 + 시스템 성능 고려 필요.
    예: 채팅방 새 메시지는 1초마다, 택배 배송 상태는 10분마다

    2. 스레드 수 관리 (특히 무한 루프일 때)

    • 폴링을 위해 새로운 스레드를 만들고 무한 루프 돌릴 때는 스레드 자원 낭비 주의
    • 자바에선 ExecutorService 같은 스레드 풀을 활용해서 스레드 개수 제한 필요
    • ⇒ new Thread(...).start(); 남발은 피하고, 스케줄러나 큐 기반 처리 권장

    3. 조건이 충족되지 않을 때 반드시 탈출 조건 고려

    • 무한 while (true) 루프 안에서 break 못 하면 프로그램이 끝나지 않고 계속 돌아간다
    • ⇒ 일정 횟수 이상 확인했는데도 안되면 timeout 처리해야 함
    int retry = 0; int MAX_RETRY = 100; // 10초 동안 확인 while (retry < MAX_RETRY) { ... retry++; } System.out.println("상품이 들어오지 않았습니다. 종료합니다.");

    4. 불필요한 리소스 점유 최소화

    • while (true) 안에 Thread.sleep()이 없으면 CPU가 쉬지 않고 루프를 계속 돌게 된다.
    • 이걸 Busy Waiting이라고 하며, CPU 자원을 100% 가까이 점유하게 된다. 100% 를 점유하게 되면 안되는 이유점은 아래와 같다.
    • 👉 문제점:
      • 해당 스레드는 계속 실행 중이라 CPU 코어를 독점함
      • 그 결과, 다른 스레드나 작업들이 CPU를 사용할 기회를 얻지 못함
      • 이는 전체 시스템 성능을 심각하게 저하시킬 수 있음
    실시간 반응성이 필요한 경우에도 짧은 주기로 sleep을 반복하며 체크하는 게 낫고, sleep 없이 무한루프는 절대 지양해야 함.

    5. 네트워크/DB polling 시에는 더 주의

    • DB나 서버에 주기적으로 요청을 보내는 polling은 부하가 훨씬 큼
    • 이때는 polling 대신 WebSocket, SSE, Webhook 같은 이벤트 기반 방식이 더 나을 수 있음

    🟠 Push 방식

    Push는 대상(서버, 객체 등)이 상태가 바뀌었을 때 스스로 알림을 보내주는 방식이다.
    “필요하면 내가 알려줄게!”
    Polling은 계속 물어보는 구조였다면, Push는 상태가 바뀌었을 때 알아서 알려주는 구조다.

    1. 코드 예시 기반 설명

    public class LotteMart implements Mart { // 구독자 명단 private List<Customer> customerList = new ArrayList<>(); // 구독 등록 @Override public void add(Customer customer) { customerList.add(customer); } // 구독 취소 @Override public void remove(Customer customer) { customerList.remove(customer); } @Override public void received() { for (int i = 0; i < 5; i++) { System.out.println("."); try { Thread.sleep(1000); } catch (InterruptedException e) { throw new RuntimeException(e); } } notify("lotteMart : 바나나"); } @Override public void notify(String msg) { for (Customer customer : customerList) { customer.update(msg); } } }
    • LotteMart가 상품이 들어오면 customer.update()를 직접 호출해서 알림을 발송한다.
    • 고객은 기다리고만 있어도 되고, 마트가 알아서 알려준다

    2. Push의 특징과 장점

    ✅ 1. 불필요한 반복 요청이 없음

    • Polling처럼 “들어왔어?”, “지금은?”, “이제는?” 이런 반복 요청이 없음
    • 네트워크, CPU, 메모리 리소스 낭비가 없다

    ✅ 2. 이벤트 기반이라 반응이 즉각적임

    • 변화가 생기자마자 바로 반응 가능
    • ex) 실시간 알림, 실시간 채팅, 실시간 주식 가격

    ✅ 3. 옵저버 패턴과 잘 맞음

    • 옵저버(Observer)들이 등록만 해두면,
    • 주제(Subject)가 알아서 상태 변경 시 알림을 푸시해줌
    • → 느슨한 결합 구조도 만들어줌

    3. Push 구현시 주의할 점

    ⚠️ 1. 관찰자(Observer) 관리 필요

    • 상태가 바뀔 때 푸시할 대상(옵저버 리스트)을 잘 관리해야 함
    • 누락되면 알림 못 받음, 중복되면 여러 번 알림

    ⚠️ 2. 비동기 처리 고려

    • 여러 observer에게 동시에 알림 보낼 땐 비동기 처리 고려
    • 한 observer가 느려도 전체 푸시가 지연될 수 있음

    ⚠️ 3. Push 실패 대응 필요

    • 네트워크 오류나 예외 발생 시, 푸시 실패할 수 있음
    • → 실패 시 재시도 로직, 큐, 로그 기록 등을 고려해야 함

    🟡 두 방식 비교 정리

    Polling과 Push는 모두 외부 상태의 변화를 감지하는 방법이다.
    하지만 "누가 주도해서 상태를 확인하는가"에 따라 다음과 같은 차이가 있다:
    • Polling : "내가 계속 물어봐야 함"
    • Push (옵저버 패턴) : "상태가 바뀌면 알려줌"
    실시간성, 리소스 효율 면에서는 Push 방식(옵저버 패턴)이 훨씬 유리하다.
    다만 구현 복잡도나 네트워크 환경에 따라 Polling을 선택하는 경우도 있다.
    Share article
    Contents
    🔴 Polling 방식1. 코드 예시 기반 설명2. Polling의 코드를 작성 할 시 주의할 점🟠 Push 방식1. 코드 예시 기반 설명2. Push의 특징과 장점3. Push 구현시 주의할 점🟡 두 방식 비교 정리

    An's Blog

    RSS·Powered by Inblog