다수의 객체를 사슬(chain)처럼 연결해두고, 그 객체의 사슬을 차례로 돌아다니며 목적한 객체를 결정하는 방법을 생각할 수 있다.
이를 Chain of Responsibility 패턴이라 한다.
예제는 '트러블이 발생해서 누군가 처리해야하는 상황'이다.
package chainofresponsibility;
/**
* 발생한 트러블을 표현하는 클래스
* @author dev-jones
*
*/
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[" + number + "]";
}
}
package chainofresponsibility;
public abstract class Support {
private String name; // 트러블 해결자의 이름
private Support next; // 떠넘기는 곳
public Support(String name) {
this.name = name;
}
/**
* 다음 해결자 설정
* @param next
* @return
*/
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);
}
}
@Override
public String toString() {
return "[" + name + "]";
}
protected abstract boolean resolve(Trouble trouble);
protected void done(Trouble trouble) {
System.out.println(trouble + " is solved by " + this + ". :)");
}
protected void fail(Trouble trouble) {
System.out.println(trouble + " cannot be resolved. :(");
}
}
package chainofresponsibility;
/**
* limit에서 지정한 번호 미만의 트러블을 해결하는 클래스
* @author dev-jones
*
*/
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;
}
}
}
package chainofresponsibility;
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;
}
}
}
package chainofresponsibility;
/**
* 지정한 번호의 트러블에 한하여 처리
* @author dev-jones
*
*/
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;
}
}
}
package chainofresponsibility;
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 number[0] is solved by [Bob]. :)
Trouble number[33] is solved by [Bob]. :)
Trouble number[66] is solved by [Bob]. :)
Trouble number[99] is solved by [Bob]. :)
Trouble number[132] is solved by [Diana]. :)
Trouble number[165] is solved by [Diana]. :)
Trouble number[198] is solved by [Diana]. :)
Trouble number[231] is solved by [Elmo]. :)
Trouble number[264] is solved by [Fred]. :)
Trouble number[297] is solved by [Elmo]. :)
Trouble number[330] cannot be resolved. :(
Trouble number[363] is solved by [Elmo]. :)
Trouble number[396] cannot be resolved. :(
Trouble number[429] is solved by [Charlie]. :)
Trouble number[462] cannot be resolved. :(
Trouble number[495] is solved by [Elmo]. :)
'자바' 카테고리의 다른 글
자바 Stream API (0) | 2021.09.25 |
---|---|
[자바] 옵저버패턴 : java.util.Observer, Observable (0) | 2021.06.27 |
[자바] Template Method 패턴 (0) | 2021.06.14 |
InputStream과 InputStreamReader (0) | 2021.06.13 |
[자바] Proxy 패턴 (0) | 2021.06.12 |