Notice
Recent Posts
Recent Comments
Link
«   2024/05   »
1 2 3 4
5 6 7 8 9 10 11
12 13 14 15 16 17 18
19 20 21 22 23 24 25
26 27 28 29 30 31
Archives
Today
Total
관리 메뉴

개발자되기 프로젝트

구조 안을 돌아다니며 처리 - Chain of Responsibility 본문

Java/디자인 패턴

구조 안을 돌아다니며 처리 - Chain of Responsibility

Seung__ 2021. 11. 15. 00:09

1. Chain of Responsibility Pattern??


  • 책임 떠넘기기
  • 다수의 객체를 사슬처럼 연결
  • 요청을 처리할 수 있는 기회를 하나 이상의 객체에게 부여함
  • 요청을 해결할 객체를 만날 때 까지 객체 고리를 따라서 요청을 전달.

 

2. 의도 (Intent)와 동기(Motivation)


  • 메세지를 보내는 객체와 이를 받아서 처리하는 객체들 간의 결합도를 줄이기 위함
  • 하나의 요청에 대한 처리가 반드시 한 객체에서만 이루어지는것이 아닌 여러 객체가 조건이 맞으면 처리의 기회를 가지게 됨
  • HELP 시스템 같은 경우 적절한 답을 찾을 때 까지 연결되어 해결할 수 있음

 

 

3. Class diagram


 

4. 객체 협력 (collaborations)


  • Handler
    • 요청을 처리하는 인터페이스를 정의하고, 다음 번 처리자와의 연결을 구현한다.
    • 연결고리에 연결된 다음 객체에게 다시 메세지를 보낸다
  • ConcreteHandler
    • 책임져야 할 메세지를 처리한다.
    • 처리못하는 메세지는 다음 수신자에게 전달한다.
  • Client
    • ConcreteHandler 객체에게 필요한 요청을 보낸다.

 

 

5. 중요한 결론 (consequence)


  • 객체들 간의 결합도가 적어진다. 요청을 처리하는 객체와 요청을 보내는 객체가 서로 모를 수 있다.
  • 연결순서는 상황에 따라 바뀌거나 추가 삭제될 수 있다. 즉 객체의 책임을 추가, 변경, 확장할 수 있다.
  • 메세지가 항상 수신된다는것을 보장할 수 없다.

 

 

6. 예제


  • Trouble(숫자)가 0부터 499까지 +33 씩 증가한다.
  • 각 Support는 처리할 수 있는 숫자의 조건을 가지고 있다.
  • 한 trouble이 주어지면 Supprot를 등록한 순서대로 태워보자. resolve가 가능하면 해당 support에서resolve하고
    그렇지 않으면 다음 support로 책임을 넘긴다.
public class Trouble {

    int number;

    public Trouble(int number) {
        this.number = number;
    }

    public int getNumber() {
        return number;
    }

    public void setNumber(int number) {
        this.number = number;
    }
}
  • next Support를 등록하고
  • support의 메서드를 정의한다.(template method, 흐름을 정의)
  • Support의 resolve 여부에 따라 응답이 달라진다.
public abstract class Support {

    private String name;
    private Support next;

    public String getName() {
        return name;
    }

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

    }

    @Override
    public String toString() {
        return "[" + next + "]";
    }

    protected abstract boolean resolve(Trouble trouble);
    protected void done(Trouble trouble){
        System.out.println(trouble.getNumber() + " is resolved by " + this.name + ".");
    }
    protected void fail(Trouble trouble){
        System.out.println(trouble.getNumber() + "cannot be resolved" + this.name + ".");
    }


}
  • 특정 범위 내의 trouble이 주어지면 처리가 가능한 support
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;
        }
    }
}
  • 아무런 처리를 하지 않는 Support
public class NoSupport extends Support{
    public NoSupport(String name) {
        super(name);
    }

    @Override
    protected boolean resolve(Trouble trouble) {
      return false;
    }
}
  • 홀수만 처리하는 support
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;
        }
    }
}
  • trouble이 정확이 일치할 때 resolve하는 support
public class SpecialSupport extends Support{

    public 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;
        }
    }
}
public class Test {

    public static void main(String[] args) {
        Support a = new NoSupport("A");
        Support b = new LimitSupport("B", 100);
        Support c = new SpecialSupport("C", 429);
        Support d = new LimitSupport("D", 200);
        Support e = new OddSupport("E");
        Support f = new LimitSupport("F", 300);

        a.setNext(b).setNext(c).setNext(d).setNext(e).setNext(f);

        for (int i=0; i< 500; i+=33){
            a.support(new Trouble(i));
        }
    }
}
0 is resolved by B.
33 is resolved by B.
66 is resolved by B.
99 is resolved by B.
132 is resolved by D.
165 is resolved by D.
198 is resolved by D.
231 is resolved by E.
264 is resolved by F.
297 is resolved by E.
330cannot be resolvedF.
363 is resolved by E.
396cannot be resolvedF.
429 is resolved by C.
462cannot be resolvedF.
495 is resolved by E.
  • 이처럼 하나의 trouble을 여러 클래스를 통해 처리가 가능하다.

 

 

7. GitHub : 211114 Chain Of Responsibility


 

GitHub - bsh6463/designPattern

Contribute to bsh6463/designPattern development by creating an account on GitHub.

github.com

 

Comments