반응형

책임 사슬 패턴(Chain of Responsibility Pattern)

  - 템플릿 메서드 패턴은 행위패턴(Behavioral Pattern) 중 하나이다.
  - 행위 패턴은 객체 사이에 알고리즘이나 책임 분배에 관련된 패턴이다.

  - 행위 패턴은 결합도를 최소화하는 것에 목표로 한다.

  - 책임 사슬 패턴은 특정한 객체가 담당하는 일반적인 방법과 다르게 객체를 연결리스트와 같은 사슬 방식으로 연결한 후에 요청을 수행하지 못하는 객체라면 다음 객체로 책임을 넘기는 형태의 패턴이다.

 

장점

  - 여러 클래스간에 걸쳐 이루어지는 일이기 때문에 구조가 다른 클래스에 대해서 낮은 결합도로 동일한 이벤트 핸들링이 가능하다. 

  - 사슬에 들어가는 객체를 바꾸거나 순서를 바꿈으로써 역할을 동적으로 추가/제거 할 수 있다. 상황에 따라 동적으로 핸들러를 추가하거나 제거할 수 있으며, 이러한 변화가 전체구조에 아무런 영향을 주지 않는다는 점에서 객체지향적인 목적을 달성한다고 볼 수 있다.

 

코드

  * 한라봉의 무게에 따라 다른 박스로 분리되는 예시

 

  - 한라봉 Chain Interface :

    책임 사슬 패턴의 핵심 Interface

    setNextChain 메소드를 통해서 다른 체인을 이어준다.

public interface HanrabongChain {

    void setNextChain(HanrabongChain nextChain);
    void weightFilter(int weight);

}

 

  - 한라봉 Class

 

public class Hanrabong {

    private int weight;

    public Hanrabong(int weight) {
        this.weight = weight;
    }

    public int getWeight() {
        return this.weight;
    }
}

 

  - 한라봉 10kg Filter Class

 

public class Hanrabong10k implements HanrabongChain{

    private HanrabongChain hanrabongChain;

    @Override
    public void setNextChain(HanrabongChain nextChain) {
        this.hanrabongChain = nextChain;
    }

    @Override
    public void weightFilter(int weight) {
        if(weight >= 10) {
            System.out.println("IN 10kg box!");
        } else {
            this.hanrabongChain.weightFilter(weight);
        }
    }
}

 

  - 한라봉 5kg Filter Class

 

public class Hanrabong5k implements HanrabongChain{

    private HanrabongChain hanrabongChain;

    @Override
    public void setNextChain(HanrabongChain nextChain) {
        this.hanrabongChain = nextChain;
    }

    @Override
    public void weightFilter(int weight) {
        if(weight >= 5) {
            System.out.println("IN 5kg box!");
        } else {
            this.hanrabongChain.weightFilter(weight);
        }
    }
}

 

  - 한라봉 3kg Filter Class

 

public class Hanrabong3k implements HanrabongChain{

    private HanrabongChain hanrabongChain;

    @Override
    public void setNextChain(HanrabongChain nextChain) {
        this.hanrabongChain = nextChain;
    }

    @Override
    public void weightFilter(int weight) {
        if(weight >= 3) {
            System.out.println("IN 3kg box!");
        } else {
            this.hanrabongChain.weightFilter(weight);
        }
    }
}

 

  - 책임 사슬 패턴 Test Class

@SpringBootTest
class HanrabongChainTest {

    @Test
    void hanrabongFilterTest() {

        HanrabongChain hanrabongChain = getHanrabongChain();

        Hanrabong hanrabong5 = new Hanrabong(5);
        Hanrabong hanrabong12 = new Hanrabong(12);
        Hanrabong hanrabong7 = new Hanrabong(7);
        Hanrabong hanrabong4 = new Hanrabong(4);
        Hanrabong hanrabong1 = new Hanrabong(1);

        List<Hanrabong> rabongList = Arrays.asList(hanrabong5, hanrabong12, hanrabong7, hanrabong4, hanrabong1);

        for (Hanrabong hanrabong : rabongList) {
            hanrabongChain.weightFilter(hanrabong.getWeight());
        }


    }
    
    // 다음 객체 연결
    private HanrabongChain getHanrabongChain() {
        HanrabongChain hanrabong10k = new Hanrabong10k();
        HanrabongChain hanrabong5k = new Hanrabong5k();
        HanrabongChain hanrabong3k = new Hanrabong3k();

        hanrabong10k.setNextChain(hanrabong5k);
        hanrabong5k.setNextChain(hanrabong3k);
        return hanrabong10k;
    }

}

 

정리

* 책임 사슬 패턴의 주의점

위 테스트 예제에서 무게가 1kg인 한라봉이 들어온다면 에러가 발생되거나 필터에 걸리지 않는다.

책임 사슬 패턴은 요청이 반드시 수행된다는 보장이 없기 때문에, 체인이 적절하게 구성되어 프로세스가 처리 될 수 있도록 구성하여야 한다. 추가적으로 요청을 처리하는데 걸리는 시간을 예측하기 힘들다는 단점도 있어 시간예측이 중요한 경우 해당 패턴의 적용을 검토해봐야 한다.

 

참조 

  - https://www.nextree.co.kr/p2533/

728x90
반응형

+ Recent posts