책임 체인 패턴

이정석·2023년 6월 20일
0

디자인패턴

목록 보기
11/23

책임 체인 패턴이란?

요청을 처리할 수 있는 객체들을 연결한 체인을 생성하고, 요청이 체인을 따라 전달되며 각 객체가 해당 요청을 처리하거나 다음 객체로 전달하는 패턴이다. 책임을 하나의 객체에 할당하는 것이 아닌 객체 집합에 요청을 전달하는 것이다.


문제상황

돈이 입력되었을 100원 50원 10원짜리 동전의 개수를 구해야 하는 상황이 있다 가정하자.
1. 동전의 개수를 세는 Change클래스는 다음과 같다

public class Change {
    public void getChange(int amount) {
        int numOf100 = amount / 100;
        amount %= 100;

        int numOf50 = amount / 50;
        amount %= 50;

        int numOf10 = amount / 10;
        amount %= 10;

        System.out.println("100원: " + numOf100);
        System.out.println("50원: " + numOf50);
        System.out.println("10원: " + numOf10);
    }
}

위 구조는 새로운 동전의 종류를 추가하거나 동전의 종류를 수정할 때 Change클래스를 수정해야 한다. 즉, OCP를 위배하는 코드라는 뜻이다.

동전 별로 개수를 구하지 말고 '동전 집단'에 개수를 구하도록 구조를 바꾸어보자


구조

  1. Handler: 요청을 처리하는 인터페이스를 정의한 클래스로 요청을 처리할 메소드와 처리하고 남은 요청을 처리할 다음 핸들러를 가진다.
  2. ConcreteHandler: Handler를 구현한 클래스로 실제 요청을 처리하는 과정을 구현한다. ConcreteHandler는 특정 유형의 요청을 처리하고 처리할 수 없는 요청은 다음 핸들러에 전달한다.

코드(JAVA)

1. Coin

public abstract class Coin {
    protected Coin nextCoin;
    protected int value;

    public void setNextCoin(Coin nextCoin) {
        this.nextCoin = nextCoin;
    }

    public void process(int amount) {
        if (amount >= value) {
            int num = amount / value;
            int remainder = amount % value;
            System.out.println(value + "원: " + num);
            if (remainder != 0) nextCoin.process(remainder);
        } else {
            nextCoin.process(amount);
        }
    }
}

handleRequest에 해당하는 process는 이를 상속받는 서브 클래스에서 재정의하는 것도 하나의 방법이지만 Coin클래스에 단위에 해당하는 value를 정의함으로 process과정을 일반화 시켰다.

2. Coin 100, 50, 10

public class Coin100 extends Coin {
    public Coin100() {
        this.value = 100;
    }
}

public class Coin50 extends Coin {
    public Coin50() {
        this.value = 50;
    }
}

public class Coin10 extends Coin {
    public Coin10() {
        this.value = 10;
    }
}

3. Client

public class Client {
    public static void main(String[] args) {
        Coin coin100 = new Coin100();
        Coin coin50 = new Coin50();
        Coin coin10 = new Coin10();

        coin100.setNextCoin(coin50);
        coin50.setNextCoin(coin10);

        coin100.process(260);
    }
}

Client라 하였지만 coin100, 50, 10을 사용하는 다른 클래스가 추가된다면 그 클래스에 coin100객체를 넘겨주면 된다.


누가 요청을 처리하나?

Handler집단에 어떤 Handler가 요청을 처리하는지는 Client는 모른다. 단지, Handler집단에 있는 어떤 객체가 요청을 처리한다는 사실만 알 수 있다.

Client의 요청을 처리할 수 없는 상황이 발생한다면 에러상황을 reply해줄 방법을 정의해주어야 한다.

profile
게임 개발자가 되고 싶은 한 소?년

0개의 댓글