취업과 기본기 튼튼/빽 투더 기본기
[디자인 패턴 14편] 행동 패턴, 책임 연쇄 (Chain of responsibility)
흠시
2020. 3. 21. 18:55
1. 개념
책임 연쇄 패턴은 요청을 처리하는 동일 인터페이스 객체들을
체인 형태로 연결해놓는 패턴이다.
앞의 객체의 요청을 처리하지 못할 경우, 같은 인터페이스의 다른 객체에게 해당 요청을 전달한다.
1.1. 구조
- Handler
- 요청을 처리하는 목적의 추상 클래스
- ConcreteHandler 가 이를 상속받아
HandleRequest()
를 구현한다.
- ConcreteHandler
- Handler 를 상속받아 요청 처리를 구현하는 구체적인 클래스
1.2. 장단점
- 이것도 역시 상황에 맞게 사용되는거라 딱히 장단점을 말할 수 는 없을 듯?
1.3. 활용 상황
- 말 그대로 객체가 동일한 인터페이스(기능)을 갖되
- 요청을 처리는데, 이 요청을 처리하지 못할 시, 이걸 처리해줄 그 다음 객체를 지정해야 할 때.
- 요청을 처리하는 '순서'를 가짐.
2. 구현
클라이언트는 다음과 같이 사용할 수 있다.
concrete_handler_1 = ConcreteHandler1()
concrete_handler_2 = ConcreteHandler2(concrete_handler_1)
# concrete_handler_1 -> concrete_handler_2 순으로 처리.
concrete_handler_2.handle_request()
구체적인 ConcreteHandler 가 구현해야하는 추상 클래스는 다음과 같다.
class Handler(metaclass=ABCMeta):
def __init__(self, successor:Handler = None) -> None:
# 연결해놓을 클래스를 successor 에 달아둔다.
self._successor = successor
@abstractmethod
def can_handle(self) -> bool:
# 여기에 해당 클래스가 처리할 수 있는지 여부를 반환.
pass
@abstractmethod
def handle_request(self) -> None:
pass
이 Handler
를 상속받아 구체적인 Handler 객체를 정의하는 ConcreteHandler
들은 다음과 같다.
class ConcreteHandler1(Handler):
def can_handle(self):
return False
def handle_request(self):
if can_handle():
# 처리 가능하면 여기서 처리하면 됨.
elif self._successor is not None:
# 처리 불가능한 경우, 다음 클래스 동작.
self._successor.handle_request()
class ConcreteHandler1(Handler):
def can_handle(self):
return True
def handle_request(self):
if can_handle():
pass
elif self._successor is not None:
self._successor.handle_request()