도서 요약 / / 2023. 1. 15. 21:15

[JAVA 언어로 배우는 디자인 패턴 입문] Chain of Responsibility 패턴

'JAVA 언어로 배우는 디자인 패턴 입문'의 내용을 정리한 것입니다.

Chain of Responsibility 패턴

  • 어떤 요청이 있을 때, 그 요청을 처리할 객체를 고정적으로 결정할 수 없는 경우
  • 이때 여러 객체를 사실처럼 연쇄적으로 묶고, 객체 사슬을 차례대로 돌면서 원하는 객체를 결정하는 방법
  • 이 패턴을 사용하면 '요청하는 쪽'과 '처리하는 쪽'의 결합을 약하게 할 수 있다.

예제 프로그램


Trouble 클래스

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 + "]";
    }
}

Support 클래스

public abstract class Support {

    private String name;

    private Support next;

    public Support(String name) {
        this.name = name;
        this.next = null;
    }

    public Support setNext(Support next) {
        this.next = next;
        return next;
    }

    public 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 resolved by " + this + ".");
    }

    protected void fail(Trouble trouble) {
        System.out.println(trouble + " cannot be resolved.");
    }
}

NoSupport 클래스

public class NoSupport extends Support {

    public NoSupport(String name) {
        super(name);
    }

    @Override
    protected boolean resolve(Trouble trouble) {
        return false;
    }
}

LimitSupport 클래스

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

OddSupport 클래스

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

SpecialSupport 클래스

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

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

실행 결과

[Trouble 0] is resolved by [Bob].
[Trouble 33] is resolved by [Bob].
[Trouble 66] is resolved by [Bob].
[Trouble 99] is resolved by [Bob].
[Trouble 132] is resolved by [Diana].
[Trouble 165] is resolved by [Diana].
[Trouble 198] is resolved by [Diana].
[Trouble 231] is resolved by [Elmo].
[Trouble 264] is resolved by [Fred].
[Trouble 297] is resolved by [Elmo].
[Trouble 330] cannot be resolved.
[Trouble 363] is resolved by [Elmo].
[Trouble 396] cannot be resolved.
[Trouble 429] is resolved by [Charlie].
[Trouble 462] cannot be resolved.
[Trouble 495] is resolved by [Elmo].

Handler(처리자) 역

  • 요구를 처리하는 인터페이스를 정의
  • 처리할 다음 사람을 준비해 두고 스스로 처리할 수 없는 요구가 나오면 그 사람에게 넘겨 준다.
  • Support 클래스가 이 역할

ConcreteHandler(구체적인 처리자) 역

  • 요구를 구체적으로 처리
  • NoSupport, LimitSupport, OddSupport, SpecialSupport 클래스가 이 역할

Client(요구자) 역

  • ConcreteHandler에 요구를 한다
  • Main 클래스가 이 역할

정리

  • 클라이언트와 실제 요청을 처리하는 처리자를 느슨하게 결합한다.
  • 클라이언트는 요구만 하면 되고 처리자는 사슬 형태로 처리자를 변경하여 처리할 수 있다.



반응형
  • 네이버 블로그 공유
  • 네이버 밴드 공유
  • 페이스북 공유
  • 카카오스토리 공유