[디자인패턴] 책임연쇄(Chain of Responsibility) 패턴
행위패턴: 객체 간 더 나은 상호작용, 책임 분배 방법 제공하는 패턴
향후 쉽게 확장할 수 있는 유연성에 대한 솔루션을 제공한다.
책임연쇄(Chain of Responsibility) 패턴
책임을 연쇄한다?
요청에 대한 처리를 각각의 책임을 가진 객체에게 넘긴다 라고 생각하면 될 거 같다.
클라이언트에 대한 요청을 하나의 객체에서 처리하는 것이 아닌 여러 처리 객체들로 나눠 이를 연결해 연쇄적으로 처리하는 행위패턴
책임연쇄패턴 구조
- Handler
요청을 수신,처리하는 인터페이스를 정의
- ConcreteHandler
요청을 처리하는 실제 객체
URL을 프로토콜, 도메인명, 포트번호로 파싱해서 정보 출력하는 로직이 존재한다고 가정한다.
클린하지 않은 코드
class Handler{
static void parsing(String url){
//프로토콜
int endIndex = url.indexOf("://");
System.out.println("PROTOCOL: " + url.substring(0,endIndex));
//도메인
int startIndex = url.indexOf("://")+ 3;
int endIndex2 = url.lastIndexOf(":");
System.out.println("DOMAIN: " + url.substring(startIndex,endIndex2));
//포트
int startIndex = url.lastIndexOf(":") + 1;
System.out.println("PORT: " + url.substring(startIndex))
};
}
만약 queryString 추가 시 포트 로직 아래에 if,else구문 등을 더하여 추가되어야 하므로
1. OCP원칙 지켜지지 않으며
2. Handler 객체의 책임이 너무 크다.
3. 순서가 바뀔시에도 OCP 위반
이런 경우, 책임 연쇄 패턴을 적용해
1. 프로토콜 핸들러
2. 도메인 핸들러
3. 포트 핸들러
4. 쿼리스트링 핸들러
로 나누어 구현할 수 있다.
책임연쇄 패턴 적용한 코드
abstract class Handler{
Handler nexthandler = null;
Handler setNext(Handler handler){
this.nexthandler = handler;
return handler; //메서드 체이닝 가능
}
abstract void parsing(String url);
public void process(String url){
this.parsing(url);
if(this.nexthandler != null){ //다음 핸들러에게 책임 넘김
this.nexthandler.process(url);
}
}
}
class ProtocolHandler extends Handler{
@Override
void parsing(String url) {
int endIndex = url.indexOf("://");
System.out.println("PROTOCOL: " + url.substring(0,endIndex));
}
}
class DomainHandler extends Handler{
@Override
void parsing(String url) {
int startIndex = url.indexOf("://")+ 3;
int endIndex = url.lastIndexOf(":");
System.out.println("DOMAIN: " + url.substring(startIndex,endIndex));
}
}
class PortHandler extends Handler{
@Override
void parsing(String url) {
int startIndex = url.lastIndexOf(":") + 1;
System.out.println("PORT: " + url.substring(startIndex));
}
}
String url = "https://www.naver.com:80";
Handler handler2 = new ProtocolHandler();
handler2.setNext(new DomainHandler()).setNext(new PortHandler()); //책임연쇄
handler2.process(url);
/*출력 내용 */
PROTOCOL: https
DOMAIN: www.naver.com
PORT: 80
적용 전 코드에선 ifelse문이 존재하지 않도록 짜놨으나 수도없이 존재할 경우
해당 패턴을 적용하여 책임을 분리하고 연쇄할 수 있다.
장점
1. 각 핸들러들의 처리에 대한 순서를 유연하게 변경가능
2. 각 핸들러마다 각자의 책임이 명확하여 파악 쉽다.
3. 새로운 요청에 대한 핸들러 생성이 쉽다
단점
1.
2.
3.
참고
💠 Chain Of Responsibility 패턴 - 완벽 마스터하기 (tistory.com)
Validation에 책임 연쇄 패턴 적용하기 | leeyh0216's devlog