본문 바로가기
개발/디자인 패턴

[Java 언어로 배우는 디자인 패턴 입문] 구조를 돌아다니기 14. Chain of Responsibility

by hongdor 2021. 1. 12.
728x90

출처 : 책 - java 언어로 배우는 디자인 패턴 입문

 

14. Chain of Responsibility - 책임 떠넘기기

 

 

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 - 해결을 위한 추상 클래스. 자기자신인 Support를 가지고 있다.

                  setNext 메소드로 다음 객체를 설정하고 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.");
    }
}

 

 

(3) NoSupport - 해결 구현 클래스 1

public class NoSupport extends Support {
    public NoSupport(String name) {
        super(name);
    }
    protected boolean resolve(Trouble trouble) {     // 해결용 메소드
        return false;                              // 자신은 아무것도 처리하지 않는다
    }
}

 

 

(4) LimitSupport - 해결 구현 클래스 2

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;
        }
    }
}

 

 

(5) OddSupport - 해결 구현 클래스 3

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;
        }
    }
}

 

(6) SpecialSupport - 해결 구현 클래스 4

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;
        }
    }
}

 

 

(7) 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));
        }
    }
}
728x90

댓글