본문 바로가기

자바

[자바] Chain of Responsibility 패턴

다수의 객체를 사슬(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