🤖

본 콘텐츠의 이미지 및 내용은 AI로 생성되었습니다.

⚠️

본 콘텐츠의 이미지 및 내용을 무단으로 복제, 배포, 수정하여 사용할 경우 저작권법에 의해 법적 제재를 받을 수 있습니다.

이미지 로딩 중...

Chain of Responsibility 패턴 트러블슈팅 가이드 - 슬라이드 1/13
A

AI Generated

2025. 11. 4. · 51 Views

Chain of Responsibility 패턴 트러블슈팅 가이드

Chain of Responsibility 패턴 사용 시 자주 발생하는 문제들과 해결 방법을 실제 코드 예제로 학습합니다. 초급 개발자를 위한 실전 트러블슈팅 가이드입니다.


카테고리:TypeScript
언어:TypeScript
메인 태그:#TypeScript
서브 태그:
#DesignPatterns#ChainOfResponsibility#ErrorHandling#BestPractices

들어가며

이 글에서는 Chain of Responsibility 패턴 트러블슈팅 가이드에 대해 상세히 알아보겠습니다. 총 12가지 주요 개념을 다루며, 각각의 개념에 대한 설명과 실제 코드 예제를 함께 제공합니다.

목차

  1. 체인_끊김_문제
  2. 체인_끊김_해결
  3. 무한_루프_문제
  4. 무한_루프_방지
  5. 책임_중복_처리
  6. 책임_명확화
  7. 반환값_손실
  8. 반환값_전파
  9. 체인_순서_오류
  10. 올바른_체인_순서
  11. 타입_안전성_부족
  12. 제네릭_타입_안전성

1. 체인 끊김 문제

개요

핸들러가 다음 핸들러를 호출하지 않아 체인이 중단되는 가장 흔한 실수입니다.

코드 예제

class Handler {
  next: Handler | null = null;

  handle(req: string) {
    if (req === "A") return "처리됨";
    // 잘못됨: next 호출 없음
    return null;
  }
}

설명

next가 있음에도 호출하지 않으면 체인이 끊깁니다. 항상 조건 불만족 시 next?.handle(req)를 호출해야 합니다.


2. 체인 끊김 해결

개요

처리할 수 없는 요청은 반드시 다음 핸들러로 전달해야 합니다.

코드 예제

class Handler {
  next: Handler | null = null;

  handle(req: string) {
    if (req === "A") return "A 처리됨";
    return this.next?.handle(req) ?? "미처리";
  }
}

설명

조건 불만족 시 this.next?.handle(req)로 다음 핸들러에게 책임을 위임합니다. null 체크로 안전하게 처리합니다.


3. 무한 루프 문제

개요

핸들러가 자기 자신을 참조하거나 순환 참조로 무한 루프가 발생합니다.

코드 예제

const h1 = new Handler();
const h2 = new Handler();
h1.next = h2;
h2.next = h1; // 위험: 순환 참조

h1.handle("unknown"); // 무한 루프!

설명

h1 → h2 → h1로 순환되어 스택 오버플로우가 발생합니다. 체인 설정 시 순환을 피해야 합니다.


4. 무한 루프 방지

개요

Set을 사용해 이미 방문한 핸들러를 추적하여 순환을 방지합니다.

코드 예제

class SafeHandler {
  next: SafeHandler | null = null;

  handle(req: string, visited = new Set()) {
    if (visited.has(this)) return "순환 감지";
    visited.add(this);
    return this.next?.handle(req, visited);
  }
}

설명

visited Set에 현재 핸들러를 추가하고, 이미 존재하면 순환으로 판단하여 중단합니다.


5. 책임 중복 처리

개요

여러 핸들러가 동일한 요청을 처리하면 의도치 않은 중복 실행이 발생합니다.

코드 예제

class LogHandler {
  next: Handler | null = null;

  handle(req: string) {
    console.log("로그:", req);
    this.next?.handle(req);
    return "처리"; // 잘못됨: 항상 처리
  }
}

설명

조건 없이 항상 처리하면 다음 핸들러도 같은 요청을 처리합니다. 명확한 책임 분리가 필요합니다.


6. 책임 명확화

개요

각 핸들러는 자신의 책임 범위를 명확히 정의하고, 처리 불가 시 즉시 위임합니다.

코드 예제

class AuthHandler {
  next: Handler | null = null;

  handle(req: Request) {
    if (req.type !== "auth")
      return this.next?.handle(req);
    return req.isValid ? "인증됨" : "거부";
  }
}

설명

type 검사로 자신의 책임 범위를 확인하고, 해당 없으면 즉시 next로 위임하여 중복을 방지합니다.


7. 반환값 손실

개요

체인의 결과를 반환하지 않으면 최종 결과를 얻을 수 없습니다.

코드 예제

class Handler {
  next: Handler | null = null;

  handle(req: string) {
    if (this.canHandle(req)) return "처리";
    this.next?.handle(req); // 잘못: 반환 안함
  }
}

설명

next.handle()의 결과를 반환하지 않으면 체인의 최종 결과가 undefined가 됩니다.


8. 반환값 전파

개요

체인의 모든 핸들러는 결과를 명시적으로 반환해야 합니다.

코드 예제

class Handler {
  next: Handler | null = null;

  handle(req: string): string | null {
    if (this.canHandle(req)) return "처리됨";
    return this.next?.handle(req) ?? null;
  }
}

설명

return 키워드로 next의 결과를 상위로 전파하고, null 병합 연산자로 기본값을 제공합니다.


9. 체인 순서 오류

개요

핸들러의 순서가 잘못되면 특정 핸들러가 실행되지 않을 수 있습니다.

코드 예제

// 잘못된 순서
const chain = new AllHandler(); // 모든 요청 처리
chain.next = new SpecificHandler(); // 절대 실행 안됨

chain.handle("specific");

설명

AllHandler가 모든 요청을 처리하면 뒤의 SpecificHandler는 실행되지 않습니다. 구체적 → 일반적 순서로 배치해야 합니다.


10. 올바른 체인 순서

개요

구체적인 핸들러를 앞에, 일반적인 핸들러를 뒤에 배치합니다.

코드 예제

const authHandler = new AuthHandler();
const logHandler = new LogHandler();
const defaultHandler = new DefaultHandler();

authHandler.next = logHandler;
logHandler.next = defaultHandler;

설명

인증 → 로깅 → 기본처리 순으로 체인을 구성하여 각 핸들러가 적절히 실행되도록 합니다.


11. 타입 안전성 부족

개요

any 타입 사용으로 잘못된 요청이 전달되어 런타임 에러가 발생합니다.

코드 예제

class Handler {
  handle(req: any) { // 위험: any 타입
    return req.data.value; // 런타임 에러 가능
  }
}

handler.handle({ wrong: "구조" });

설명

any 타입은 타입 검사를 우회하여 잘못된 데이터 구조로 인한 에러를 컴파일 시점에 발견하지 못합니다.


12. 제네릭 타입 안전성

개요

제네릭을 사용해 타입 안전한 체인을 구성합니다.

코드 예제

interface Request { type: string; }

class Handler<T extends Request> {
  next: Handler<T> | null = null;

  handle(req: T): string | null {
    return this.next?.handle(req) ?? null;
  }
}

설명

제네릭 T로 요청 타입을 제한하고, Request 인터페이스로 최소 구조를 보장하여 타입 안전성을 확보합니다.


마치며

이번 글에서는 Chain of Responsibility 패턴 트러블슈팅 가이드에 대해 알아보았습니다. 총 12가지 개념을 다루었으며, 각각의 사용법과 예제를 살펴보았습니다.

관련 태그

#TypeScript #DesignPatterns #ChainOfResponsibility #ErrorHandling #BestPractices

#TypeScript#DesignPatterns#ChainOfResponsibility#ErrorHandling#BestPractices

댓글 (0)

댓글을 작성하려면 로그인이 필요합니다.