클로저와 옵저버 패턴

lionloopy·2025년 10월 2일
0

오늘의 공부

목록 보기
17/22
post-thumbnail

클로저란?

: 함수와 그 함수가 선언될 때의 렉시컬 환경(외부 변수 스코프)을 함께 기억하는 개념
✅ 즉, 함수 안에서 외부 변수에 접근하고, 그 상태를 유지할 수 있는 기능

옵저버 패턴이란?

: 한 객체의 상태가 바뀌면 그 객체에 의존하는 다른 객체들한테 연락이 가고, 자동으로 내용이 갱신되는 방식으로, 일대다 의존성을 정의한다.
✅ 구현 방법에는 여러가지가 있지만, 대부분 주제와 옵저버 인터페이스가 들어있는 클래스 디자인으로 한다.

  • subject: 이벤트를 발생시키는 주체
  • observer: subject에 등록되어 상태 변화 이벤트를 받음
    💡 observer가 subject에 구독함 -> subject 상태 변경 시 notify() 호출 -> observer는 콜백을 통해 상태를 전달받음

예) 네트워크 지연/오류 모니터링

  • subject: (네트워크 모니터)
    - 일정 주기로 ping을 날려 엔드포인트 체크
    • 네트워크가 느리거나 끊기면 상태를 offline으로 변경
    • 상태가 바뀌면 모든 옵저버에게 알림
  • observer: (에러 페이지 라우터, ui 표시 컴포넌트)
    - 네트워크 모니터에 구독
    • 에러 페이지로 라우팅

싱글톤 객체

: 애플리케이션 전체에서 단 하나만 존재하는 인스턴스
✅ 전역적으로 공유되며, 여러곳에서 같은 상태를 사용해야 할 때 유용하다.

  • 한 번 생성하면 재사용
  • 여러 모듈/컴포넌트에서 동일한 상태 공유
  • 여러 컴포넌트에서 호출해도 동일한 상태를 공유
  • 전역에서 네트워크 모니터를 하나만 두고 싶은 경우 적합
import { ref, onUnmounted } from 'vue';
import { useRouter } from 'vue-router';
import { createSlowNetworkMonitor, SlowNetworkStatus } from '@/utils/slowNetworkMonitor';

// 전역에 선언 -> 앱 전체에 공유되는 변수
let slowNetworkMonitor: ReturnType<typeof createSlowNetworkMonitor> | null = null;
let subscriberCount = 0;

export function useSlowNetworkMonitor() {
  const router = useRouter();
  const isSlowNetwork = ref(false);
  const latency = ref(0);

// 전역에서 단 하나 -> 싱글톤
  if (!slowNetworkMonitor) {
    slowNetworkMonitor = createSlowNetworkMonitor({
      threshold: 500,
      interval: 60000,
      autoPulling: true,
    });
  }

// 구독자 수 체크
  subscriberCount++;

// 구독 취소 시 
  const unsubscribe = slowNetworkMonitor.onChange((status: SlowNetworkStatus) => {
    isSlowNetwork.value = status.isSlowNetwork;
    latency.value = status.latency;

    if (status.isSlowNetwork) {
      router.replace('/errors/network-error');
    }
  });

  onUnmounted(() => {
    unsubscribe();
    subscriberCount--;

    if (subscriberCount === 0 && slowNetworkMonitor) {
      slowNetworkMonitor.destroy();
      slowNetworkMonitor = null;
    }
  });

  return {
    isSlowNetwork,
    latency,
  };
}
profile
기록은 담백하게, 성장은 빠르게! 🐘

0개의 댓글