컴퓨터과학/0 + 소프트웨어 아키텍처(디자인 패턴)

[소프트웨어 아키텍처] 9. 책임 연쇄 패턴(CoR: Chain of Responsibility Pattern -java)

힘들면힘을내는쿼카 2022. 11. 29. 17:54
728x90
반응형

책임 연쇄 패턴(CoR: Chain of Responsibility Pattern)

책임 연쇄 패턴은 핸들러들의 체인(사슬)을 따라 요청을 전달할 수 있게 해주는 행동 디자인 패턴 입니다.
각 핸들러는 요청을 받으면 요청을 처리할지, 다음 핸들러로 전달할지 결정 합니다.

쉽게 이야기하면, 1개의 요청을 2개 이상의 객체에서 처리해야 한다면?!
책임 연쇄 패턴을 사용하면 좋습니다.!!
요청을 처리할지 다음 핸들러로 전달할지 결정하면 되기 때문이죠!

CoR은 윈도우 시스템에서 마우스 클릭과 키보드 이벤트를 처리할 때 흔히 사용됩니다.

책임 연쇄 패턴 구조

  • Handler
    • 모든 구상 핸들러에 공통적인 인터페이스
    • 일반적으로 요청을 처리하기 위한 단일 메소드만 포함
    • 체인의 다음 핸들러를 세팅하기 위한 다른 메소드를 포함할 수도 있음
  • ConcretHandler
    • 요청을 처리하기 위한 실제 코드를 포함
    • 각 핸들러는 요청을 받으면 요청을 처리할지 다음 핸들러로 전달할지 결정

자리 배정 애플리케이션 개발

개발자들을 위한 컨퍼런스가 개최 되었습니다.!!
회사에 등록된 개발자들에게 자리를 배정해주는 애플리케이션을 만들어 봅시다.!

여기서는 interface를 사용하지 않고, abstract를 사용했습니다.

MemberAuthenticationHandler

public abstract class MemberAuthenticationHandler {
    protected MemberAuthenticationHandler handler;

    public void setHandler(MemberAuthenticationHandler handler) {
        this.handler = handler;
    }

    // parameter에 String이 아니라 Object를 넣어도 되겠죠?
    public abstract void handleRequest(String request);
}

MemberIdHandler

public class MemberIdHandler extends MemberAuthenticationHandler {
    @Override
    public void handleRequest(String request) {
        System.out.println("=========================");
        if(request.contains("_100_")) {
            System.out.println("회원 인증 완료");
            super.handler.handleRequest(request);
        } else {
            System.out.println("회원 등록을 해주세요.");
        }
    }
}

DepartmentHandler

public class DepartmentHandler extends MemberAuthenticationHandler {
    @Override
    public void handleRequest(String request) {
        if(request.contains("dev1")) {
            System.out.println("개발1팀 입니다.");
            super.handler.handleRequest(request);
        } else if (request.contains("dev2")) {
            System.out.println("개발2팀 입니다.");
            super.handler.handleRequest(request);
        } else if (request.contains("dev3")) {
            System.out.println("개발3팀 입니다.");
            super.handler.handleRequest(request);
        } else {
            System.out.println("개발팀 소속이 아닙니다.");
        }
    }
}

SeatNumberHandler

public class SeatNumberHandler extends MemberAuthenticationHandler {
    @Override
    public void handleRequest(String request) {
        if(request.contains("_1000")) {
            System.out.println("좌석 번호 = 1 ~ 10사이에 자유롭게 착성해주세요.");
        } else if(request.contains("_2000")) {
            System.out.println("좌석 번호 = 11 ~ 20사이에 자유롭게 착성해주세요.");
        } else if(request.contains("_3000")) {
            System.out.println("좌석 번호 = 21 ~ 30사이에 자유롭게 착성해주세요.");
        } else {
            System.out.println("좌석이 없습니다. 관리자에게 문의 하세요.");
        }
    }
}

Client

public class Client {
    public static void main(String[] args) {
        MemberAuthenticationHandler handler1 = new MemberIdHandler();
        MemberAuthenticationHandler handler2 = new DepartmentHandler();
        MemberAuthenticationHandler handler3 = new SeatNumberHandler();

        handler1.setHandler(handler2);
        handler2.setHandler(handler3);

          // 1개의 요청
        handler1.handleRequest("dev1_100_1000");
        handler1.handleRequest("pm1_100_1000");
        handler1.handleRequest("dev2_100_2000");
        handler1.handleRequest("dev1_100_3000");
        handler1.handleRequest("dev1_100_4000");
    }
}

결과

=========================
회원 인증 완료
개발1팀 입니다.
좌석 번호 = 1 ~ 10사이에 자유롭게 착성해주세요.
=========================
회원 인증 완료
개발팀 소속이 아닙니다.
=========================
회원 인증 완료
개발2팀 입니다.
좌석 번호 = 11 ~ 20사이에 자유롭게 착성해주세요.
=========================
회원 인증 완료
개발1팀 입니다.
좌석 번호 = 21 ~ 30사이에 자유롭게 착성해주세요.
=========================
회원 인증 완료
개발1팀 입니다.
좌석이 없습니다. 관리자에게 문의 하세요.

책임 연쇄 패턴의 장단점

장점

  • 요청을 보낸 쪽과 받는 쪽을 분리할 수 있다.
  • 객체는 사슬의 구조를 몰라도 됩니다.!
    • 사슬에 들어 있는 다른 객체의 직접적인 레퍼런스를 가질 필요도 없습니다.!!
      • 객체를 단순하게 설계 할 수 있습니다.!!!
  • 사슬에 들어가는 객체를 바꾸거나 순서를 바꿈으로써 역할을 동적으로 추가하거나 제거할 수 있습니다.!

단점

  • 요청시 반드시 수행된다는 보장이 없다.(사슬 끝까지 갔는데도 처리되지 않을 수도 있음)
    • 이런 특성이 장점이 될수도 있다.
  • 실행 시 과정을 살펴보거나 디버깅하기가 힘들다.

 

 

출처 : https://refactoring.guru/ko/design-patterns/chain-of-responsibility

728x90
반응형