책임 사슬 패턴(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인 한라봉이 들어온다면 에러가 발생되거나 필터에 걸리지 않는다.
책임 사슬 패턴은 요청이 반드시 수행된다는 보장이 없기 때문에, 체인이 적절하게 구성되어 프로세스가 처리 될 수 있도록 구성하여야 한다. 추가적으로 요청을 처리하는데 걸리는 시간을 예측하기 힘들다는 단점도 있어 시간예측이 중요한 경우 해당 패턴의 적용을 검토해봐야 한다.
참조
'JAVA > Design Pettern' 카테고리의 다른 글
[Design Pattern] 프로토타입 패턴 (0) | 2022.04.27 |
---|---|
[Design Pattern] 커맨드 패턴 (0) | 2022.03.25 |
[Design Pattern] 템플릿 메서드 패턴 (0) | 2022.03.23 |
[Design Pattern] 프록시 패턴 (0) | 2022.03.22 |
[Design Pattern] 추상 팩토리 패턴 (0) | 2022.03.19 |