본문 바로가기
Design Pattern/행동 패턴(Behavioral Patterns)

책임 연쇄(Chain of Responsibility) - 행동 패턴(Behavioral Patterns)

by 김 민 준 2024. 5. 25.

 

책임 연쇄 패턴은 요청을 처리할 수 있는 일련의 처리 개체(Handler)들을 연결해 두고, 각 개체가 요청을 처리할 수 있는 기회를 가지도록 하는 디자인 패턴이다. 이 패턴을 사용하면 요청을 처리할 개체를 명시적으로 결정하지 않고, 여러 개체가 처리할 수 있는 기회를 가지게 된다.

 

예시로 생각해보자

 

고객 지원 시스템이 있다. 고객 지원 시스템에서 고객의 요청을 처리하는 단계가 일반적으로 많이 들어가 있다. 

고객의 요청은 처음에 일반 지원 직원에게 전달되고, 그 직원이 처리할 수 없는 요청은 상급자나 관리자에게 전달된다

 

이때 책임 연쇄 패턴으로 구현할 수 있다 

 

주요 개념부터 알아보자 

 

1. Handler(처리자) : 요청을 처리하거나 다음 처리자에게 전달한다.

2. ConcreateHandler(구체적인 처리자) : 요청을 실제로 처리하거나 처리할 수 없는 경우 다음 처리자에게 전달 한다. 

3. Client(클라이언트) 요청을 처리자에게 전달한다. 

 

예시 코드를 확인하여 이해해보자.

 

// Handler 인터페이스: 요청 처리의 공통 인터페이스 정의
interface Handler {
    void setNextHandler(Handler nextHandler);
    void handleRequest(String request);
}

 

// ConcreteHandler 클래스: 구체적인 처리자
class SupportStaff implements Handler {
    private Handler nextHandler;

    @Override
    public void setNextHandler(Handler nextHandler) {
        this.nextHandler = nextHandler;
    }

    @Override
    public void handleRequest(String request) {
        if (request.equals("Basic Issue")) {
            System.out.println("Support Staff handles the basic issue.");
        } else {
            if (nextHandler != null) {
                nextHandler.handleRequest(request);
            }
        }
    }
}

class Manager implements Handler {
    private Handler nextHandler;

    @Override
    public void setNextHandler(Handler nextHandler) {
        this.nextHandler = nextHandler;
    }

    @Override
    public void handleRequest(String request) {
        if (request.equals("Advanced Issue")) {
            System.out.println("Manager handles the advanced issue.");
        } else {
            if (nextHandler != null) {
                nextHandler.handleRequest(request);
            }
        }
    }
}

class Director implements Handler {
    private Handler nextHandler;

    @Override
    public void setNextHandler(Handler nextHandler) {
        this.nextHandler = nextHandler;
    }

    @Override
    public void handleRequest(String request) {
        if (request.equals("Critical Issue")) {
            System.out.println("Director handles the critical issue.");
        } else {
            if (nextHandler != null) {
                nextHandler.handleRequest(request);
            }
        }
    }
}

 

// 클라이언트 코드
public class ChainOfResponsibilityDemo {
    public static void main(String[] args) {
        // 처리자들을 설정
        Handler supportStaff = new SupportStaff();
        Handler manager = new Manager();
        Handler director = new Director();

        // 책임 연쇄 설정
        supportStaff.setNextHandler(manager);
        manager.setNextHandler(director);

        // 요청 처리
        supportStaff.handleRequest("Basic Issue");
        supportStaff.handleRequest("Advanced Issue");
        supportStaff.handleRequest("Critical Issue");
        supportStaff.handleRequest("Unknown Issue");
    }
}

 

//출력

//Support Staff handles the basic issue.
//Manager handles the advanced issue.
//Director handles the critical issue.

 

예제 소스코들를 보면 클라이언트는 처리자 체인을 구성하고 요청을 처리자에게 전달한다. 

핸들러 인터페이스는 요청을 처리하거나 다음 처리자에게 전달하는 메서드를 정의했다.

구체적인 처리자 클래스는 요청 처리 로직을 구현하며, 처리할 수 없는 경우 다음 처리자에게 요청한다.

 

개념으로는 일반적으로도 많이 겪는 개념이기에 추가 설명은 필요하지 않을 것 같다.