Chain of Responsibility Pattern 이란?

  • 명령 객체와 일련의 처리 객체를 포함하는 디자인 패턴
  • 요청을 처리할 수 있는 객체가 둘 이상 존재하여 한 객체가 처리하지 못하면 다음 객체로 넘어가는 형태
  • 요청을 처리할 수 있는 객체들이 사슬(Chain)로 묶여있어 어떤 요청이 들어왔을 때
    첫 번째 객체가 처리할 수 없다면, 그 요청을 처리해줄 수 있을 때까지 연쇄작용으로 다음 객체에게 처리 양도

  • Handler : 요청을 처리해주는 기능을 가지는 객체 인터페이스, 자신이 요청을 처리 못할 시 다음 객체에게 요청 넘김
  • ConcreteHandler : 실제로 요청을 처리하는 객체를 구현하는 클래스

책임 연쇄 패턴 적용

  • 자판기에서 커피를 주문하는 상황, 커피를 제공하기 위해선 총 3가지 단계를 수행, 객체들은 한 가지 기능만 수행
    1. 종이컵 준비
    2. 커피 재료 투하
    3. 뜨거운 물 투하

Handler - 요청을 처리해주는 기능을 가지는 객체 인터페이스, 자신이 요청을 처리 못할 시 다음 객체에게 요청 넘김

package BehavioralPattern.ChainofResposibility;

public interface Handler {
    public void requestHandler(Request request);
}
package BehavioralPattern.ChainofResposibility;

// 실제 요청
public class Request {
    private int level;

    public Request() {
        this.level = 1;
    }

    public int getLevel() {
        return level;
    }

    public void setLevel(int count) {
        this.level = count;
    }
}

ConcreteHandler - 실제로 요청을 처리하는 객체를 구현하는 클래스

package BehavioralPattern.ChainofResposibility;

public class PaperCup implements Handler{
    private Handler nextHandler;

    public Handler getNextHandler() {
        return nextHandler;
    }

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

    @Override
    public void requestHandler(Request request) {
        int level = request.getLevel();
        System.out.println("Level : " + level + " : 종이컵 준비");
        request.setLevel(level+1);

        if(level < 3 && this.nextHandler != null) {
            this.nextHandler.requestHandler(request);
        }
    }
}

public class Coffee implements Handler{
    private Handler nextHandler;

    public Handler getNextHandler() {
        return nextHandler;
    }

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

    @Override
    public void requestHandler(Request request) {
        int level = request.getLevel();
        System.out.println("Level : " + level + " : 커피 재료 투하");
        request.setLevel(level+1);

        if(level < 3 && this.nextHandler != null) {
            this.nextHandler.requestHandler(request);
        }
    }
}

public class HotWater implements Handler{
    private Handler nextHandler;

    public Handler getNextHandler() {
        return nextHandler;
    }

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

    @Override
    public void requestHandler(Request request) {
        int level = request.getLevel();
        System.out.println("Level : " + level + " : 뜨거운 물 투하");
        request.setLevel(level+1);

        if(level < 3 && this.nextHandler != null) {
            this.nextHandler.requestHandler(request);
        }
    }
}

Client & 실행결과

  • 책임 연쇄 패턴을 사용하면 요청을 보내는 객체와 요청을 처리해주는 객체를 분리하여 구현하기에
    두 객체들 간의 결합도를 낮출 수 있으며, 동적으로 처리 가능하다.
package BehavioralPattern.ChainofResposibility;

public class Client {
    public static void main(String[] args) {
        PaperCup first = new PaperCup();
        Coffee second = new Coffee();
        HotWater third = new HotWater();

        first.setNextHandler(second);
        second.setNextHandler(third);

        first.requestHandler(new Request());
    }
}

+ Recent posts