학습 목표

  • 요청을 처리하는 객체들을 체인(연결 구조)으로 구성하는 방법 이해
    • 요청을 보낸 쪽과 처리하는 객체 간의 결합도를 낮출 수 있음.
  • 하나의 요청을 여러 처리자가 순차적으로 검사하고 처리하는 구조 습득
  • 객체 간 강한 의존성을 줄여 유연하고 확장 가능한 구조 설계
  • 분기문(if/switch) 남발을 줄여 코드 유지보수를 쉽게 하는 방법 이해
  • 핸들러 추가/변경 시 기존 코드 수정 최소화하기

상황 예제

  • 회사 결재 시스템
    • 직원이 물품 구매 요청을 한다.
    • 처리자는 아래 순서로 사슬처럼 연결:
      1. 팀장 (최대 50만 원 승인 가능)
      2. 부장 (최대 200만 원 승인 가능)
      3. 이사 (200만 원 이상 승인)
    요청 금액에 따라 어떤 결재자가 승인할지 자동으로 결정됨.
  • 웹 서버 요청 필터링
    1. 인증 처리
    2. 권한 확인
    3. 속도 제한 검사
    4. 요청 처리
    각 단계는 “내가 처리할 수 있으면 처리하고, 아니면 다음으로 넘김”.
  • HTTP 요청이 들어오면 다음 순서로 처리:
  • 고객센터 문의 처리가 순서로 해결 가능 여부를 판단하며 넘어감.
  • 고객 질문 → 챗봇 → 1차 상담 → 전문 상담 → 관리자

예제

더보기
  • 회사 결재 시스템
    • 직원이 물품 구매 요청을 한다.
    • 처리자는 아래 순서로 사슬처럼 연결:
      1. 팀장 (최대 50만 원 승인 가능)
      2. 부장 (최대 200만 원 승인 가능)
      3. 이사 (200만 원 이상 승인)
    요청 금액에 따라 어떤 결재자가 승인할지 자동으로 결정됨.
  • handle
public abstract class Handler {
    protected Handler next;

    public Handler setNext(Handler next) {
        this.next = next;
        return next;
    }

    public abstract void handleRequest(int amount);
}
  • 구현체 책임
public class Manager extends Handler {
    @Override
    public void handleRequest(int amount) {
        if (amount <= 500000) {
            System.out.println("팀장 승인: " + amount + "원");
        } else if (next != null) {
            next.handleRequest(amount);
        }
    }
}

public class Director extends Handler {
    @Override
    public void handleRequest(int amount) {
        if (amount <= 2000000) {
            System.out.println("부장 승인: " + amount + "원");
        } else if (next != null) {
            next.handleRequest(amount);
        }
    }
}

public class Executive extends Handler {
    @Override
    public void handleRequest(int amount) {
        System.out.println("이사 최종 승인: " + amount + "원");
    }
}
  • 실행
public class Main {

    public static void main(String[] args) {
        Handler manager = new Manager();
        Handler director = new Director();
        Handler exec = new Executive();

        manager.setNext(director).setNext(exec);

        manager.handleRequest(300000);   // 팀장 처리
        manager.handleRequest(1500000);  // 부장 처리
        manager.handleRequest(5000000);  // 이사 처리
    }
}

- 금액에 따라 자동으로 결제를 해야 하는 대상이 골라지는 로직입니다.

 

마무리

좀 더 보기 좋게 한 줄로 표기되면서 가시성이 높아질 것 같고, 실제 예제로 생각나는 장면은 예전 결제 로직에서 특정 금액에 따라 할인율이 달라지는 로직이 있었는데 해당 로직 같은걸 해결이 가능했을 것 같습니다.

+ Recent posts