Chain of Responsibility패턴은 다수의 클래스가 다른 클래스의 처리 능력을 파악하지 않은 상태에서 요청 내용을 처리할 수 있게 하는 패턴이다.이 패턴은 이런 클래스들을 아주 세밀하게 결합하도록 한다.이때 유일한 공통 링크는 해당 클래스 간에 전달되는 요청 내용일 뿐이다.요청 내용은 해당 클래스들 중 하나가 요청 내용을 처리할 때까지 계속해서 전달 된다.
구조
역할
- Handler: Request를 처리하기 위한 인터페이스를 정의한다. Successor링크를 구현한다.
- Concrete Handler:자신이 책임지고 있는request를 처리한다. successor에 접근할 수 있다. Request를 처리할 수 있으면 그렇게 하고,아니면successor에게 전달한다.
- Client: Request를 만들어 체인 상의 첫ConcreteHandler에게 전달한다.
의도
어떤request에 대해서 한 개 이상의 오브젝트에게 처리할 기회를 줌으로써,그request의sender와receiver를decoupling한다. Receiver가 될 수 있는 오브젝트들을 연결하여 체인을 만들고, request가 처리될 때 까지 체인을 따라 전달한다.
적용시기
- 프로그램이 요구하는 작업에 적합한 유사한 메소드들을 여러 개의 객체가 가질 경우,그러나 개발자가 호출 코드에 객체의 역할을 지정해 주기보다는 객체가 스스로 처리 작업을 결정하도록 하는 것이 좀더 바람직하다.
- 객체들 중 한가지가 가장 적합할 경우,그러나 특정 객체를 선택하기 위해if-else문이나switch문을 사용하여 코드를 작성하고 싶지 않을 경우
- 프로그램이 실행중일 때 일련의 프로세싱 옵션을 추가하려는 새로운 객체가 존재할 경우
- 때때로 한 개 이상의 객체가 요청에 따라 작업을 수행해야 할 경우 그리고 개발자는 호출하는 프로그램이 이런 상호 작용 정보를 포함하려고 하지 않을 경우
결론
l 이 패턴의1차적인 목적은 다른 패턴들처럼 객체 간의 의존성을 약화시키는 것이다.따라서 하나의 객체는 다른 객체에게 요청 내용을 전달하는 방법만 파악해 두면 된다.
l 체인 안의 각각의 자바 객체는 자체적으로 내장되어 있다.각 객체들은 다른 객체에 대한 정보는 전혀 없고,자신이 요청 내용을 충족시킬 수 있는지의 여부를 결정할 수 있는 능력만 보유하면 된다.이런 점은 각각의 객체를 작성하는 일뿐만 아니라 체인을 생성하는 작업을 매우 쉽게 한다.
l 개발자는 체인 안에서 마지막 객체가 전달한 모든 요청 내용을 처리할 수 있는지 또는 해당 요청 사항을 단지 무시해 버리는지를 판단할 수 있다.그러나 이와 같은 작업을 효율적으로 수행하려면,개발자가 해당 체인의 마지막 객체가 어느 객체인지 파악하고 있어야 한다.
l 마지막으로 자바 언어는 다중 상속을 허용하지 않으므로 기본chain클래스는 각각의 객체들이 다른 계층 구조를 상속할 수 있도록abstract클래스보다는 인터페이스를 필요로 하게 된다.이런 접근은 각각의 모듈에서 코드 내용을 링크하고,전송하며,전달하는 작업을 개별적으로 구현해야 한다는 것이 단점이다. (또는 이번 예제처럼chain인터페이스를 구현하는concrete클래스를 서브 클래스화 하는 경우도 포함된다.)
예제소스
|
예제 소스
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 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 NoSupport extends Support { public NoSupport(String name) { super(name); } protected boolean resolve(Trouble trouble) { 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; } } } public class Trouble { private int number; public Trouble(int number) { this.number = number; } public int getNumber() { return number; } public String toString() { return "[Trouble " + number + "]"; } } public class mainClass { public static void main(String[] args) { mainClass client = new mainClass(); client.exec(); } public void exec() { Support 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)); } } } |
관련패턴
l Composite패턴과 종종 혼용된다.이 경우,컴포넌트의parent가successor가 된다.
'Programming > Design Pattern' 카테고리의 다른 글
[펌] The Flyweight Pattern (0) | 2006.01.21 |
---|---|
[펌] Chapter 5 Behavioral Patterns(행위 패턴) (0) | 2006.01.21 |
[펌] The Command Pattern (0) | 2006.01.21 |
[펌] The Facade Pattern (0) | 2006.01.21 |
[펌] The Flyweight Pattern (0) | 2006.01.21 |