1) 의미
같은 입력부분의 내용에 따라 출력에 대해 다른 객체
로 작업하여 보내야 하는 경우, 해당 패턴을 이용해서
매칭되는 객체를 찾아서 결과를 낼수 있는 방법입니다.
이때 사슬처럼 쭉 연결해 놓고 적절성 유무를 판단후 다음 객체로
넘기기 때문에 체인이라 이름붙었습니다.
좋은점은 입력시에 결과에 어떤 객체를 사용할지 생각하지 않고
쓸수 있습니다.
단점은 속도 문제는 있을수 있습니다.
2. 소스
1) Trouble는 발생한 문제를 표현합니다.
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) Support 클래스는 발생한 문제에 대한 해결을 위해
구현할 클래스입니다.
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.");
}
}
구현할 클래스입니다.
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) 서포트를 상속하여 연결 대상이 되는 클래스를
작성합니다.
public class NoSupport extends Support {
public NoSupport(String name) {
super(name);
}
protected boolean resolve(Trouble trouble) { // 해결용 메소드
return false; // 자신은 아무 처리도 하지 않는다.
}
}
작성합니다.
public class NoSupport extends Support {
public NoSupport(String name) {
super(name);
}
protected boolean resolve(Trouble trouble) { // 해결용 메소드
return false; // 자신은 아무 처리도 하지 않는다.
}
}
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;
}
}
}
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;
}
}
}
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;
}
}
}
4) 테스트 메인소스를 작성합니다.
public class Main {
public static void main(String[] args) {
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));
}
}
}
public class Main {
public static void main(String[] args) {
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));
}
}
}
결과 :
[Trouble 0] is resolved by [Bob].
[Trouble 33] is resolved by [Bob].
[Trouble 66] is resolved by [Bob].
[Trouble 99] is resolved by [Bob].
[Trouble 132] is resolved by [Diana].
[Trouble 165] is resolved by [Diana].
[Trouble 198] is resolved by [Diana].
[Trouble 231] is resolved by [Elmo].
[Trouble 264] is resolved by [Fred].
[Trouble 297] is resolved by [Elmo].
[Trouble 330] cannot be resolved.
[Trouble 363] is resolved by [Elmo].
[Trouble 396] cannot be resolved.
[Trouble 429] is resolved by [Charlie].
[Trouble 462] cannot be resolved.
[Trouble 495] is resolved by [Elmo].
[Trouble 0] is resolved by [Bob].
[Trouble 33] is resolved by [Bob].
[Trouble 66] is resolved by [Bob].
[Trouble 99] is resolved by [Bob].
[Trouble 132] is resolved by [Diana].
[Trouble 165] is resolved by [Diana].
[Trouble 198] is resolved by [Diana].
[Trouble 231] is resolved by [Elmo].
[Trouble 264] is resolved by [Fred].
[Trouble 297] is resolved by [Elmo].
[Trouble 330] cannot be resolved.
[Trouble 363] is resolved by [Elmo].
[Trouble 396] cannot be resolved.
[Trouble 429] is resolved by [Charlie].
[Trouble 462] cannot be resolved.
[Trouble 495] is resolved by [Elmo].
3. 다이어그램
https://ko.wikipedia.org/wiki/Chain_of_responsibility_%ED%8C%A8%ED%84%B4https://sourcemaking.com/design_patterns/chain_of_responsibility
4. 관련패턴
1) Composite pattern
2) Command Pattern
댓글 없음:
댓글 쓰기