'JAVA 언어로 배우는 디자인 패턴 입문'의 내용을 정리한 것입니다.
Chain of Responsibility 패턴
- 어떤 요청이 있을 때, 그 요청을 처리할 객체를 고정적으로 결정할 수 없는 경우
- 이때 여러 객체를 사실처럼 연쇄적으로 묶고, 객체 사슬을 차례대로 돌면서 원하는 객체를 결정하는 방법
- 이 패턴을 사용하면 '요청하는 쪽'과 '처리하는 쪽'의 결합을 약하게 할 수 있다.
예제 프로그램
Trouble 클래스
public class Trouble {
private int number;
public Trouble(int number) {
this.number = number;
}
public int getNumber() {
return number;
}
@Override
public String toString() {
return "[Trouble " + number + "]";
}
}
Support 클래스
public abstract class Support {
private String name;
private Support next;
public Support(String name) {
this.name = name;
this.next = null;
}
public Support setNext(Support next) {
this.next = next;
return next;
}
public void support(Trouble trouble) {
if (resolve(trouble)) {
done(trouble);
} else if (next != null) {
next.support(trouble);
} else {
fail(trouble);
}
}
@Override
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.");
}
}
NoSupport 클래스
public class NoSupport extends Support {
public NoSupport(String name) {
super(name);
}
@Override
protected boolean resolve(Trouble trouble) {
return false;
}
}
LimitSupport 클래스
public class LimitSupport extends Support {
private int limit;
public LimitSupport(String name, int limit) {
super(name);
this.limit = limit;
}
@Override
protected boolean resolve(Trouble trouble) {
if (trouble.getNumber() < limit) {
return true;
} else {
return false;
}
}
}
OddSupport 클래스
public class OddSupport extends Support {
public OddSupport(String name) {
super(name);
}
@Override
protected boolean resolve(Trouble trouble) {
if (trouble.getNumber() % 2 == 1) {
return true;
} else {
return false;
}
}
}
SpecialSupport 클래스
public class SpecialSupport extends Support {
private int number;
public SpecialSupport(String name, int number) {
super(name);
this.number = number;
}
@Override
protected boolean resolve(Trouble trouble) {
if (trouble.getNumber() == number) {
return true;
} else {
return false;
}
}
}
Main 클래스
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].
Handler(처리자) 역
- 요구를 처리하는 인터페이스를 정의
- 처리할 다음 사람을 준비해 두고 스스로 처리할 수 없는 요구가 나오면 그 사람에게 넘겨 준다.
- Support 클래스가 이 역할
ConcreteHandler(구체적인 처리자) 역
- 요구를 구체적으로 처리
- NoSupport, LimitSupport, OddSupport, SpecialSupport 클래스가 이 역할
Client(요구자) 역
- ConcreteHandler에 요구를 한다
- Main 클래스가 이 역할
정리
- 클라이언트와 실제 요청을 처리하는 처리자를 느슨하게 결합한다.
- 클라이언트는 요구만 하면 되고 처리자는 사슬 형태로 처리자를 변경하여 처리할 수 있다.
반응형