#Chain of Responsibility

 

 

1. 개념

 

Chain of Responsibility(책임 사슬)패턴

어떤 하나의 문제가 발생했을 경우

그 문제의 처리를 담당하는 여러개의 처리기를 두고

순서대로 처리해 나가는 패턴을 말한다.

 

자바에서 바로 try/catch/finally

책임 사슬 패턴을 적용한 예이다.

try{}블럭 안에서 예외가 발생했을 경우

catch{}블럭으로 이동하는데

어떤 예외인지에 따라 어떤 catch{}블럭이 실행되는지 결정되는 행위가

역할 사슬 패턴이라는 것이다.

 

 

2. Why? 왜 사용해야 할까?

 

프로젝트를 수행하다보면 무수히 많은 객체들을 생성하게 된다.

자신이 만든 모든 객체의 위치와 내용을 다시 기억해 내기란

실질적으로 힘든 경우가 있다.

이처럼

어떤 요청에 대해 처리해주는 객체의 위치를 파악하기 어려운 상황에 대비하여

이러한 요청을 처리해주는 객체들의 집합체나 계층화가 되어있으면

사용자는 굳이 객체의 위치를 알 필요없이

손쉽게 요청을 처리할 수 있다.

 

 

3. 장단점

 

책임 사슬 패턴을 사용하면 모든 후보 객체들을

다 알 필요없이 단순하게

자신과 연결된 단 하나의 후보 객체만 알면된다.

이처럼 객체들 간의 상호작용 과정을 단순화시키기에

객체 간의 결합도가 낮아지는 방법이 된다.

 

객체의 책임을 여러 객체에게 분산시키는 과정에서

상속을 이용하므로

객체의 기능을 추가, 삭제 및 수정하기 용이하다.

 

그러나 이 방식은 요청이 처리된다는 보장이 없다.

객체들 간의 연결고리가 잘 정의되어 있어야 하며

객체들 중 아무도 요청을 처리하지 못했을 경우

요청은 그냥 버려질 수 있다는 가능성이 있다.

이때 Exception을 던지는 방식 등으로 대처를 할 수 있다.

 

 

4. 클래스 다이어그램

 

5. 예제 코드

 

코드 예제는 java에서 Exception에서 아이디어가 떠올랐다.

실제 구동되는 동작은 다르지만 이해가 수월하길 바란다.

 

Exception 객체들은 모두 Problem 객체에 의해 관리되고 있으며

하위 클래스에서 자신이 처리할 수 있는 에러인지 확인하고

객체를 생성하는 코드를 구현해보았다.

public abstract class Problem {
	
	private static Problem[] list = {new SocketException(), new NullPointException(), new IOException()};
	protected static Integer num = 0;
	protected static String msg;
	
	public static Problem next(String error) {
		msg = error;
		
		if(num == list.length) {
			System.out.println("어떤 에러인지 확인 불가능");
			return null;
		}
		
		return list[num++].cause();
	}

	
	public abstract Problem cause();
}

 

하위 클래스 Exception객체들은 다음과 같이 구현되었다.

public class SocketException extends Problem{

	@Override
	public Problem cause() {
		if("socket".equals(msg)) {
			System.out.println("소켓 문제 발생! SocketException 객체 생성");
			num = 0;
			return this;
		}
		
		//다음 객체 ㄱㄱ
		return next(msg);
	}
}

public class NullPointException extends Problem{

	@Override
	public Problem cause() {
		
		if("null".equals(msg)) {
			System.out.println("객체에 Null 값이 들어감. NullPointException 객체 생성");
			num = 0;
			return this;
		}
		
		//다음 객체 ㄱㄱ
		return next(msg);
		
	}
}

public class IOException extends Problem{

	@Override
	public Problem cause() {
		
		if("IO".equals(msg)) {
			System.out.println("입력 값 오류 발생! IOException 객체 생성");
			num = 0;
			return this;
		}
		
		//다음 객체 ㄱㄱ
		return next(msg);
	}

}

 

클라이언트에서 에러가 발생해 Problem 객체를 호출하고

문제의 원인을 물어보는 코드를 구현했다.

public class Client {

	public static void main(String[] args) {
		
		System.out.println("에러 발생!");
		System.out.println("");
		
		
		//입력 오류로 에러가 발생한 경우
		System.out.println("입력 오류가 발생한 경우");
		Problem problem1 = Problem.next("IO");
		System.out.println("");
		
		//객체에 null값으로 에러가 발생한 경우
		System.out.println("null 값으로 에러가 난 경우");
		Problem problem2 = Problem.next("null");
			

	}

}

 

정리하자면 Client에서 오류가 발생하였고

Problem 객체를 이용하여 오류에 해당하는 객체를 생성하는 과정의 코드이다.

결과는 다음과 같이 나온다.

 

6. 참고

 

https://leetaehoon.tistory.com/64

https://ehclub.co.kr/2210

https://blog.naver.com/2feelus/220655715030

http://egloos.zum.com/iilii/v/3863886

GoF의 디자인 패턴

 

 

Made by 꿩

 

 

'스터디 > GoF의 디자인패턴' 카테고리의 다른 글

Strategy Pattern  (0) 2019.04.30
Template Method Pattern  (0) 2019.04.30
Decorator Pattern  (0) 2019.04.28
Factory Method Pattern  (0) 2019.04.23

+ Recent posts