책임 연쇄 패턴
특정 요청이 들어올 경우, 해당 요청을 연결리스트와 같은 사슬 방식으로 객체끼리 연결하여 요청을 수행하지 못할 경우, 다음 객체에 떠넘기는 형태의 패턴.
책임 연쇄 패턴 특징
•
SRP : 단일 책임 원칙, 하나의 객체에서는 하나의 책임만 담당한다.
•
OCP : 개방 폐쇄 원칙, 기존 코드를 해하지 않고 확장할 수 있다.
•
요청 처리 순서를 제어할 수 있다.
→ 결합을 느슨하게 하기 위해 고안됨. 프로그래밍에서 가장 좋은 사례.
대표적인 예
•
Java try~catch
•
스프링 시큐리티
•
Clean architecture
•
window dom 구조
UML 1
1.
Handler : 모든 구체적인 핸들러에 공통적인 인터페이스를 선언합니다. 일반적으로 요청을 처리하기 위한 단일 메서드만 포함하지만 때로는 체인에서 다음 핸들러를 설정하기 위한 다른 메서드가 있을 수도 있습니다.
2.
BaseHandler : 는 모든 핸들러 클래스에 공통 코드를 넣을 수 있는 기본 클래스입니다.
일반적으로 이 클래스는 다음 핸들러에 대한 참조를 저장하기 위한 필드를 정의합니다. 클라이언트는 핸들러를 이전 핸들러의 생성자 또는 설정자에 전달하여 체인을 구축할 수 있습니다. 클래스는 기본 처리 동작을 구현할 수도 있습니다. 즉, 존재 여부를 확인한 후 다음 처리기로 실행을 전달할 수 있습니다.
3.
생성자 : 에는 요청을 처리하기 위한 실제 코드가 포함되어 있습니다. 요청을 받으면 각 핸들러는 요청을 처리할지 여부와 함께 체인을 따라 전달할지 여부를 결정해야 합니다.
핸들러는 일반적으로 자체 포함되고 변경할 수 없으며 생성자를 통해 필요한 모든 데이터를 한 번만 수락합니다.
4.
클라이언트 는 응용 프로그램의 논리에 따라 체인을 한 번만 구성하거나 동적으로 구성할 수 있습니다. 요청은 체인의 모든 핸들러로 보낼 수 있습니다. 첫 번째 핸들러일 필요는 없습니다.
UML 2
요청을 보내는 쪽(sender)과 요청을 처리하는(receiver) 쪽을 분리하는 패턴.
•
-> 핸들러 체인을 사용해서 요청을 처리한다.
예제
public abstract class Handler {
public String name;
private Handler next;
public Handler(String name) {
this.name = name;
}
public void setNext(Handler next) {
this.next = next;
}
public void handleRequest(int number) {
if (canHandle(number)) {
print(number);
// chain이 연결되어 있으면 다음 처리 객체에 문제 전달 (oddHandler -> evenHandler 순으로 처리)
} else if (next != null) {
next.handleRequest(number);
} else {
System.out.println("처리할 수 있는 객체 없음");
}
}
public void print(int number) {
System.out.println(number + ":" + name + "로 처리");
}
public abstract boolean canHandle(int number);
}
Java
복사
public class OddHandler extends Handler {
public OddHandler(String name) {
super(name);
}
public boolean canHandle(int number) {
return number % 2 != 0;
}
}
Java
복사
public class EvenHandler extends Handler {
public EvenHandler(String name) {
super(name);
}
public boolean canHandle(int number) {
return number % 2 == 0;
}
}
Java
복사
// main
Handler oddHandler = new OddHandler("홀수");
Handler evenHandler = new EvenHandler("짝수");
// chain 연결 oddHandler -> evenHandler
oddHandler.setNext(evenHandler);
for (int i = 1; i <= 10; i++) {
oddHandler.handleRequest(i);
}
Java
복사
단점
•
디버깅이 어렵다. (특정 체인을 찾아야하며, 시간 체크가 어렵다.)
•
객체 폭발이 일어난다.요청을 보내는 쪽(sender)과 요청을 처리하는(receiver) 쪽을 분리하는 패턴.
•
-> 핸들러 체인을 사용해서 요청을 처리한다.