반응형
1. 책임 연쇄 패턴이란?
클라이언트로부터의 요청을 처리할 수 있는 처리객체를 집합(Chain)으로 만들어 부여함으로 결합을 느슨하기 위해 만들어진 디자인 패턴이다.
다음과 같은 상황일 때 책임 연쇄 패턴을 고려할 수 있다.
- 요청의 발신자와 수신자를 분리하는 경우
- 요청을 처리할 수 있는 객체가 여러개일 때 그 중 하나에 요청을 보내려는 경우
- 코드에서 처리객체(handler)를 명시적으로 지정하고 싶지 않은 경우
2. 샘플 코드
구조 자체는 데코레이터 패턴과 비슷하기 때문에 데코레이터 패턴에서 사용했던 예제를 그대로 사용했다.
ParamHandler
public abstract class ParamHandler
{
private ParamHandler mHandler = null;
public ParamHandler(ParamHandler handler)
{
this.mHandler = handler;
}
public void checkParam(Hashtable<String, String> params)
{
if (mHandler != null)
{
mHandler.checkParam(params);
}
}
}
UML에서 Handler의 역할을 하는 추상클래스이다. 연쇄적인 처리를 가능하게 하는 핵심적인 클래스라고 볼 수 있다.
주의할 점은 체인의 끝지점에는 처리 객체가 null이기 때문에 꼭 null 체크를 해주어야 한다는 것이다.
ReplaceParamHandler
public class ReplaceParamHandler extends ParamHandler
{
public ReplaceParamHandler(ParamHandler handler)
{
super(handler);
}
@Override
public void checkParam(Hashtable<String, String> params)
{
params.replaceAll((k, v) -> v = filterSpcStrings(v));
super.checkParam(params);
}
private String filterSpcStrings(String value)
{
StringBuffer strBuff = new StringBuffer();
for (int i = 0; i < value.length(); i++)
{
char c = value.charAt(i);
switch(value.charAt(i)){
case 60: // '<'
strBuff.append("<");
break;
case 62: // '>'
strBuff.append(">");
break;
case 38: // '&'
strBuff.append("&");
break;
case 34: // '"'
strBuff.append(""");
break;
case 39: // '\''
strBuff.append("'");
break;
default:
strBuff.append(c);
break;
}
}
return strBuff.toString();
}
}
conCreateHandler의 역할을 하는 구현체이다.
인젝션 방어를 위해 주요 특수문자를 치환하는 기능을 담당하고 있다.
TrimParamHandler
public class TrimParamHandler extends ParamHandler
{
public TrimParamHandler(ParamHandler handler) {
super(handler);
}
@Override
public void checkParam(Hashtable<String, String> params)
{
trimValue(params);
super.checkParam(params);
}
private void trimValue(Hashtable<String, String> param)
{
param.replaceAll((k, v) -> v =
v.trim());
}
}
conCreateHandler의 역할을 하는 구현체이다.
파라미터 값들의 공백을 지워주는 역할을 한다.
Client
public class Client
{
public static void main(String[] args)
{
Hashtable<String, String> params = new Hashtable<>();
params.put("uid", " 55 ");
params.put("title", "제목입니다.");
params.put("contents", "select * from table where uid > 35");
System.out.println("매개변수 필터링 전 : " + params.toString());
ParamHandler service = new TrimParamHandler(
new ReplaceParamHandler(null)
);
service.checkParam(params);
System.out.println("매개변수 필터링 후 : " + params);
}
}
결과
3. 장단점
1) 장점
- 객체간의 결합도를 낮출 수 있다.
- 처리 객체를 여러개 만들었을 때 순서를 바꾸거나 기능을 조합할 수 있다.
2) 단점
- 디버깅할 때 확인해야 할 것 들이 많아진다 (처리 객체 순서, 처리 함수 호출 순서)
- 연결 방식 때문에 런타임에 무한루프가 발생할 수 있다.
반응형
'Pattern > GOF' 카테고리의 다른 글
행위패턴 - 옵저버패턴 (0) | 2022.06.09 |
---|---|
구조패턴 - 프록시 (0) | 2022.05.26 |
구조패턴 - 데코레이션 패턴 (0) | 2022.05.24 |
구조패턴 - 컴포짓패턴 (0) | 2022.05.23 |
생성패턴 - 팩토리메서드 (0) | 2022.05.11 |