Java

[Design Pattern] 책임 떠넘기기 패턴(Chain of Responsibility Pattern)

구루싸 2020. 7. 12. 22:04
반응형
SMALL

또 한주가 끝나가네요-_-
다시 월요일...
화이팅..!

이번 학습 주제는

디자인 패턴 중

책임 떠넘기기(Chain of Responsibility)
패턴입니다

이 패턴은 어떤 요청이 발생했을 때

그 요청을 처리할 오브젝트를

직접 결정할 수 없을 경우

복수의 오브젝트를 사슬(chain) 처럼
연결하고 그 오브젝트를 차례로
돌아다니면서(방문하면서)

목적한 오브젝트를 결정하는 방법입니다
그럼 언제나처럼

책임 떠넘기기 패턴의

역할들을 정리하고 시작하겠습니다

역할설명
Handler(처리자)요구를 처리하는 인터페이스를 결정
Concrete Handler(구체적인 처리자)요구를 처리하는 구체적인 역할
Client(요구자)Concrete Handler 역할에 요구

이제 구현을 해보겠습니다

1. 클래스(Abstract Class) Trouble.java

package chainOfResponsibilityPattern;

public class Trouble {
	private int number;
	public Trouble(int number) {
		this.number = number;
	}
	public int getNumber() {
		return number;
	}
	public String toString() {
		return "[Trouble " + number + "]";
	}
}

2. 추상 클래스(Abstract Class) Support.java

package chainOfResponsibilityPattern;

public abstract class Support {
	private String name;
	private Support next;
	public Support(String name) {
		this.name = name;
	}
	public Support setNext(Support next) {
		this.next = next;
		return next;
	}
	public final void support(Trouble trouble) {
		if ( resolve(trouble) ) {
			done(trouble);
		} else if ( next != null ) {
			next.support(trouble);
		} else {
			fail(trouble);
		}
	}
	public String toString() {
		return "[" + name + "]";
	}
	protected abstract boolean resolve(Trouble trouble);
	protected void done(Trouble trouble) {
		System.out.println(trouble + " is resolved by " + this + ".");
	}
	protected void fail(Trouble trouble) {
		System.out.println(trouble + " cannot be resolved.");
	}
}

3. 클래스(Class) NoSupport.java

package chainOfResponsibilityPattern;

public class NoSupport extends Support {
	public NoSupport(String name) {
		super(name);
	}
	protected boolean resolve(Trouble trouble) {
		return false;
	}
}

4. 클래스(Class) LimitSupport.java

package chainOfResponsibilityPattern;

public class LimitSupport extends Support {
	private int limit;
	public LimitSupport(String name, int limit) {
		super(name);
		this.limit = limit;
	}
	protected boolean resolve(Trouble trouble) {
		if ( trouble.getNumber() < limit ) {
			return true;
		} else {
			return false;
		}
	}
}

5. 클래스(Class) OddSupport.java

package chainOfResponsibilityPattern;

public class OddSupport extends Support {
	public OddSupport(String name) {
		super(name);
	}
	protected boolean resolve(Trouble trouble) {
		if ( trouble.getNumber() % 2 == 1) {
			return true;
		} else {
			return false;
		}
	}
}

6. 클래스(Class) SpecialSupport.java

package chainOfResponsibilityPattern;

public class SpecialSupport extends Support {
	private int number;
	public SpecialSupport(String name, int number) {
		super(name);
		this.number = number;
	}
	protected boolean resolve(Trouble trouble) {
		if ( trouble.getNumber() == number ) {
			return true;
		} else {
			return false;
		}
	}
}

7. 클래스(Class) Test.java

import chainOfResponsibilityPattern.*;
public class Test {
	public static void main(String[] args) {
		/* Chain Of Reponsibility Pattern */
		Support alice = new NoSupport("Alice");
		Support bob = new LimitSupport("Bob", 100);
		Support charlie = new SpecialSupport("Charlie", 429);
		Support diana = new LimitSupport("Diana", 200);
		Support elmo = new OddSupport("Elmo");
		Support fred = new LimitSupport("Fred", 300);
		alice.setNext(bob).setNext(charlie).setNext(diana).setNext(elmo).setNext(fred);
		for ( int i = 0; i < 500; i += 33 ) {
			alice.support(new Trouble(i));
		}
	}
}

이 패턴은 언제 유용할까요??

만약 이 패턴을 사용하지 않는다면

어떤 한 클래스가

각 구체적인 Support 클래스들의

정보를 다 알고 있거나

어딘가에 그 정보를 관리하고 있어서
이런 요청이 대해서는
이 오브젝트가 수행하도록 해야합니다
다시말하면 일의 분담 역할을
직접 수행해야합니다

물론 이 방법이 더 빠른 방법이고

속도가 중요한 경우에는

당연히 이 방법을 선택해야하지만

아닌 경우에 책임 떠넘기기 패턴을

사용하면 될 것 같네요~

이런 것은 Trade-off 문제입니다

다음 주제는 창구(Facade) 패턴으로

시스템의 외부에 대해서는

단순한 인터페이스를 보여주고

내부에 있는 각 클래스의 역할이나

의존관계를 생각해서 정확한 순서로

클래스를 이용하는 패턴입니다

아무튼 너무 피곤한 관계로

이것으로 오늘의 학습을 마치겠습니다

그럼 이만-_-

 

 

반응형
LIST