Coding, Filming, and Nothing
article thumbnail

체인 반응, 책임 떠 넘기기 패턴 


0. 대략적인 개념

어떤 요청이 발생한 경우, 처리하는 패턴들 중 Chain of Responsibility pattern을 사용하는 방법

책임 떠 넘기기(교재 내 번역) 패턴은 다음 담당자에게로

진짜 담당자를 찾을 때 까지 리퀘스트가 설정된 순서대로 넘겨지는 것을 의미한다.

 

어떤 요청이 발생한 경우에, 그 요청할 처리할 오브젝트를 직접 결정할 수 없는 경우에 사용된다.

복수의 오브젝트(객체)를 사슬처럼 연결해 그 사슬을 돌아다니며 문제를 해결할 Target Obj.를 결정한다.

 

해당 패턴을 사용함으로써 Clinet와 Handler를 고립시킬 수 있다.

물론 체인의 제일 앞에 위치한 Handler는 알아야 한다. 그 이후로는 Chain에서 자동으로 처리 된다. 

 

Loose Connection between Requester & Server

 

 

1. 예시코드

 

 

 

예시코드

Support class에 구현되어 있는. Support.setNext() 메소드를 사용하여 (Linked List의 next pointer 처럼) next instance를 설정한다. 

setNext()의 리턴은 설정된 객체가 되게끔하여서 메소드의 체인호출을 가능하게 수행한다. 메소드의 체인호출은 Chain of Resp.의 필수는 아니다. 그러나 이렇게 메소드를 구현하면 객체의 동작이 어떻게 되는지 금방 이해할 수 있어서 좋다.

 

Trouble instance를 생성해서, Support 객체에게 Request를 수행한다. 이때, 첫번째에 위치한 alice 객체에게만 Trouble을 제공하며 다른 객체들은 체인으로 연결되어 있어서 자동으로 Trouble instance를 처리한다. 

 

 

아래는 Abstract Class 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; // return 을 통해 객체를 돌려줌으로써 method Chain을 구성할 수 있음
    }
    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.");
    }
}

setNext를 통해서 chain을 구성한다.

 

 

 

 

프로그램 실행의 결과

 

각각의 concrete Handler 에 의해서 문제가 잘 처리되고 있는 결과가 출력 된다. 

 

 

 

2. 장점? 

 이 패턴을 사용하지 않으면 생성/발생된 요구 마다 '해당 요구'는 (특정한) 누군가가 중앙집권적으로 가지고 있어야한다. 

그런데 request를 client가 수행하는데, 해당 정보를 Client에게 갖게 하는 것은 전혀 바람직하지 않다. 객체 모듈로써의 독립성이 훼손된다. 

이는 Handler도 마찬가지이다. 

 

결국에 해당 포맷을 사용하지 않으면 항상 이벤트 처리에 있어서 중재와 전체정보가 필요하므로

결정을 담당할 대법권이 추가적으로 필요하다. 

 

 

책임 떠넘기기를 통해 자기의 일에 대해 집중을 할 수 있다는 장점이 있다. 

Client와 특정 Handler를 사전에 전부 mapping을 할 필요가 없다는 점이 있다. 프로그래밍하기 쉬워진다.

또, Client는 첫번째 Handler만 알면 나머지는 전혀 몰라도 되어 독립성을 가질 수 있다. 

 

Chain Responsibility는 물론 각각을 전부 mapping하는 것보다는 속도가 느리다. 

하지만 client가 어떤 request를 요청할지에 대해서 미리 알 수가 없고 속도보다는 유연한 처리가 필요한 환경에서 용이한 방법이다.

profile

Coding, Filming, and Nothing

@_안쑤

포스팅이 좋았다면 "좋아요❤️" 또는 "구독👍🏻" 해주세요!