๋ฐ์ํ
Chain of Responsibility Pattern
Chain of Responsibility Pattern์ ์์ฒญ์ ์ฒ๋ฆฌํ ์ ์๋ ๊ธฐํ๋ฅผ ์ฌ๋ฌ ๊ฐ์ฒด๋ค์๊ฒ ๋ถ์ฌํจ์ผ๋ก์จ ๊ทธ๋ค ๊ฐ์ ๊ฒฐํฉ๋๋ฅผ ์์ ์ฃผ๋ ํจํด์ ๋๋ค.
- ๋ณต์์ Object๋ฅผ ์ฌ์ฌ์ฒ๋ผ ์ฐ๊ฒฐํด์ฃผ๋ฉด, ๊ทธ ์ค๋ธ์ ํธ์ ์ฌ์ฌ์ ์ฐจ๋ ๋๋ก ๋์๋ค๋๋ฉด์ ๋ชฉ์ ํ Object๋ฅผ ๊ฒฐ์ ํ๋ ๋ฐฉ๋ฒ์ ๋๋ค.
- responsibility ๊ฐ๋ ์ ๊ฐ๋ ๋ชจ๋๋ค์ ์ฒด์ธ์ ๋ง๋๋ Pattern ์ ๋๋ค.
- chain of responsibility pattern์ด ์๋ ๊ฒฐ์ ์์
- ํด๋ผ์ด์ธํธ ์ฝ๋์์ ๊ฒฐ์ ์์ฒญ์ ๋ฐํ ํฉ๋๋ค.
- ๊ฒฐ์ ์์ฒญ ์์๋ ๊ฒฐ์ ๋ฐฉ๋ฒ๊ณผ ๊ธ์ก์ด ์กด์ฌํฉ๋๋ค.
- ๊ฒฐ์ ๋ฐฉ๋ฒ์๋ cash, credit card, debit card ๋ฑ์ด ์์ต๋๋ค.
- ๊ฒฐ์ ์์ฒญ์ ์ฒ๋ฆฌํ๋ ํจ์๋ ํด๋์ค๊ฐ ์์ด์ผ ํ๋๋ฐ ์๋ก์ด ๊ฒฐ์ ๋ฐฉ๋ฒ์ ์ถ๊ฐํ๊ณ ์์ ํ ๋๋ง๋ค ์ฝ๋์ ๊ธธ์ด๊ฐ ๊ธธ์ด์ง๊ณ ๋ณต์กํด์ง๋๋ค.
- ๊ฒฐ์ ๋ฐฉ๋ฒ์ ๋ฐ๋ผ ๋ชจ๋์ ๋ง๋๋ ๊ฒ๋ถํฐ ์์ํฉ๋๋ค.
- Cash Handler, Credit Card Handler, Debit Card Handler๋ฅผ ์์ฑํฉ๋๋ค.
- ๊ฐ Handler๋ฅผ ์ฒด์ธ์ผ๋ก ๋ฌถ์ต๋๋ค.
Cash Handler๋ฅผ ๋ง๋๊ณ ๊ฒฐ์ ๋ฐฉ๋ฒ์ด Cash์ธ ๊ฒ์ ํ์ธํ๊ณ ๋ฐ๋ก ๊ฒฐ์ ๋ฅผ ์๋ฃํฉ๋๋ค.
- ๊ฒฐ์ ๋ฐฉ๋ฒ์ด Debit Card์ด๋ฏ๋ก Cash Handler, Credit Card Handler๊ฐ ์ฒ๋ฆฌํ ์ ์์ผ๋ฏ๋ก, ๋ค์ Handler์๊ฒ ๋๊ธฐ๊ณ ๊ฒฐ๊ตญ Debit Card Handler๊ฐ ์ฒ๋ฆฌํฉ๋๋ค.
Example: ๊ฒฐ์ ์์คํ
Base class
class Handler:
def __init__(self):
self.next_handler = None
def setNext(self, handler):
self.next_handler = handler
def handle(self, req):
if self.next_handler:
return self.next_handler.handle(req)
print("All handlers failed")
return None
- __init__
- ๋ด๋ถ์ ๋ค์ Handler๋ฅผ ๊ฐ๋ฆฌํค๋ next_handler ๊ฐ ์กด์ฌํฉ๋๋ค.
- setNext()
- ๋ค์ Handler์ธ next_handler๋ฅผ ์ค์ ํฉ๋๋ค.
- handle()
- ๊ฒฐ์ ์์ฒญ์ด ๋ค์ด์ค๋ฉด ์คํ์ํค๋ ํจ์์ ๋๋ค.
- Argument๋ก request ์ ๋ณด๊ฐ ์์ต๋๋ค.
- ๋ค์ Handler๊ฐ ์กด์ฌํ๋ฉด next_handler์ handle ํจ์๋ฅผ ์คํํฉ๋๋ค.
- ์กด์ฌํ์ง ์์ ๊ฒฝ์ฐ, None์ Return ํฉ๋๋ค.
Cache Handler
class CashHandler(Handler):
def handle(self, req):
if req['method'] == 'cash':
print(f"processing cash {req['amount']} won")
else:
print(f"CashHandler cannot process")
super().handle(req)
class CreditCardHandler(Handler):
def handle(self, req):
if req['method'] == 'creditCard':
print(f"processing creditCard {req['amount']} won")
else:
print(f"CreditCardHandler cannot process")
super().handle(req)
class DebitCardHandler(Handler):
def handle(self, req):
if req['method'] == 'debitCard':
print(f"processing debitCard {req['amount']} won")
else:
print(f"DebitCardHandler cannot process")
super().handle(req)
- CashHandler - handle()
- Base class์ handleํจ์๋ฅผ override ํฉ๋๋ค.
- ๊ฒฐ์ ๋ฐฉ๋ฒ์ด 'cash'์ผ ๊ฒฝ์ฐ, ๊ฒฐ์ ๋ฅผ ์ฒ๋ฆฌํฉ๋๋ค.
- 'cash'๊ฐ ์๋ ๊ฒฝ์ฐ, ์ฒ๋ฆฌํ ์ ์๋ค๊ณ ์ถ๋ ฅ ํ Base class์ handle()ํจ์๋ฅผ ๋ถ๋ฅด๊ธฐ ์ํด super().handle๋ฅผ ํธ์ถํ๊ณ req๋ฅผ ์ธ์๋ก ๋๊ฒจ์ค๋๋ค. (๋ค์ Handler์๊ฒ ๋๊ฒจ์ฃผ๋ ๋ถ๋ถ)
- CreditCardHandler
- CashHandler์ ๋์ผํ ๋ฐฉ์
- Method๊ฐ "creditCard"์ผ ๊ฒฝ์ฐ ์ฒ๋ฆฌ
- DebitCardHandler
- CashHandler์ ๋์ผํ ๋ฐฉ์
- Method๊ฐ "debitCard"์ผ ๊ฒฝ์ฐ ์ฒ๋ฆฌ
cash_handler = CashHandler()
creditcard_handler = CreditCardHandler()
debitcard_handler = DebitCardHandler()
cash_handler.setNext(creditcard_handler)
creditcard_handler.setNext(debitcard_handler)
- ๊ฐ Handler์ Object๋ฅผ ์์ฑํฉ๋๋ค.
- setNext ํจ์๋ฅผ ํตํด ์ธ ๊ฐ์ Handler๋ฅผ ์ฒด์ธ์ฒ๋ผ ๋ฌถ์ต๋๋ค.
payment = {
"method": "cash",
"amount": 10000
}
cash_handler.handle(payment)
- ๊ฒฐ์ ๋ฐฉ์์ด "cash"์ธ payment๋ฅผ ์์ฑํฉ๋๋ค.
- ์ฒซ ๋ฒ์งธ ๋ชจ๋์ธ CashHandler์์ ๋ฐ๋ก ์ฒ๋ฆฌํฉ๋๋ค.
payment = {
"method": "debitCard",
"amount": 10000
}
cash_handler.handle(payment)
- ๊ฒฐ์ ๋ฐฉ์์ด "debit card"์ธ payment๋ฅผ ์์ฑํฉ๋๋ค.
- CashHandler์ CreditCardHandler์์๋ ์ฒ๋ฆฌ๋ฅผ ๋ชปํ๊ณ DebitCardHandler์์ ์ฒ๋ฆฌ๋ฉ๋๋ค.
payment = {
"method": "paypal",
"amount": 10000
}
cash_handler.handle(payment)
- ๊ฒฐ์ ๋ฐฉ์์ด "paypal"์ธ payment๋ฅผ ์์ฑํฉ๋๋ค.
- ์ธ ๊ฐ์ง Handler ๋ชจ๋ ํด๋น ์๋๋ฏ๋ก ์ฒ๋ฆฌํ์ง ๋ชปํฉ๋๋ค.
๊ฐ๋ ํ์ฅ
๋ฑ์ฅ์ธ๋ฌผ
- Handler: ์๊ตฌ๋ฅผ ์ฒ๋ฆฌํ๋ ์ธํฐํ์ด์ค๋ฅผ ๊ฒฐ์ ํ๋ ์ญํ ์ ํฉ๋๋ค.
- '๋ค์ ๋ด๋น์'๋ฅผ ์ค๋นํด ๋๊ณ ์์ ์ด ์ฒ๋ฆฌํ ์ ์๋ ์๊ตฌ๊ฐ ๋์ค๋ฉด ๊ทธ ๋ด๋น์์๊ฒ ๋ ๋๊ธฐ๊ธฐ๋ฅผ ํฉ๋๋ค. ๋ฌผ๋ก '๋ค์ ๋ด๋น์'๋ Handler ์ญํ ์ ํฉ๋๋ค.
- ConcreteHandler: ์๊ตฌ๋ฅผ ์ฒ๋ฆฌํ๋ ๊ตฌ์ฒด์ ์ธ ์ญํ ์ ํฉ๋๋ค.
- Client: ์ต์ด์ ConcreteHandler ์ญํ ์ ์๊ตฌํ๋ ์ผ์ ํฉ๋๋ค.
์๊ตฌํ๋ ์ฌ๋๊ณผ ์๊ตฌ๋ฅผ ์ฒ๋ฆฌํ๋ ์ฌ๋์ ์ ์ฐํ๊ฒ ์ฐ๊ฒฐ
- Client๋ ์ต์ด๋ก ๋ง๋๋ ๋ด๋น์์๊ฒ ์๊ตฌํ๋ฉฐ, ๋ท์ผ์ ์ฌ์ค ์์ผ๋ก ๊ทธ ์๊ตฌ๊ฐ ์ ๋ฌ๋์ด ์ ์ ํ ๋ค๋ฅธ ๋ด๋น์์ ์ํด ์ฒ๋ฆฌ๋ฉ๋๋ค.
- ๋ง์ฝ Chain of Responsibility๋ฅผ ์ฌ์ฉํ์ง ์์ผ๋ฉด ‘์ด ์๊ตฌ๋ ์ด ๋ด๋น์๊ฐ ์ฒ๋ฆฌํด์ผ ํ๋ค’๋ผ๋ ์ ๋ณด๋ฅผ ๋๊ตฐ๊ฐ ์ค์์ง๊ถ์ ์ผ๋ก ๊ฐ์ง๊ณ ์์ด์ผ ํฉ๋๋ค.
- ์ด๋ฌํ ์ ๋ณด๋ฅผ ‘์๊ตฌํ๋ ์ฌ๋’์๊ฒ ๊ฐ๊ฒ ํ๋ ๊ฒ์ ํ๋ช
ํ ๋ฐฉ๋ฒ์ด ์๋๋๋ค.
- ์๊ตฌํ๋ ์ฌ๋์ด ๋ด๋น์๋ค์ ์ญํ ๋ถ๋ด๊น์ง ์์ธํ๊ฒ ์์์ผ ํ๋ค๋ฉด ๋ถํ์ผ๋ก์์ ๋ ๋ฆฝ์ฑ์ด ํผ์๋๊ธฐ ๋๋ฌธ์ ๋๋ค.
๋์ ์ผ๋ก ์ฌ์ค์ ํํ๋ฅผ ๋ณ๊ฒฝ
- ์๊ตฌ๋ฅผ ์ฒ๋ฆฌํ๋ ConcreteHandler ์ญํ ์ ์ค๋ธ์ ํธ ๊ด๊ณ๊ฐ ๋์ ์ผ๋ก ๋ณํํ๋ ์ํฉ์ด ์์ ๋, ConcreteHandler ์ญํ ์ ์ฌํธํ ์ ์์ต๋๋ค.
- ๋ง์ฝ, CoR ํจํด์ ์ฌ์ฉํ์ง ์๊ณ ํ๋ก๊ทธ๋จ ์์ ‘์ด ์๊ตฌ๋ผ๋ฉด ์ด ๋ด๋น์’๋ผ๋ ๋์ ๊ด๊ณ๊ฐ ๊ณ ์ ์ ์ผ๋ก ๊ธฐ์ ๋์ด ์์ผ๋ฉด ํ๋ก๊ทธ๋จ ์คํ ์ค์ ์ฒ๋ฆฌ์๋ฅผ ๋ณ๊ฒฝํ๊ธฐ ์ด๋ ต์ต๋๋ค.
์์ ์ ์ผ์ ์ง์ค
- ๋ ๋๊ธฐ๊ธฐ๋ ๋ถ์ ์ ์๋ฏธ๊ฐ ๊ฐํ์ง๋ง, ๊ฐ ์ค๋ธ์ ํธ๋ ์์ ์ ์ผ์ ์ง์คํ ์ ์๋ค๋ ์๋ฏธ๊ฐ ๋๊ธฐ๋ ํฉ๋๋ค.
- ๊ฐ๊ฐ์ ConcreteHandler ์ญํ ๋ค์ด ์ฌ์ฉํด์ผ ํ ์ฒ๋ฆฌ์ ๋ํ ๊ฒ๋ค์ด ๊ณ ์ ํ ๋ด์ฉ์ผ๋ก ์ง์คํ ์ ์๊ฒ ๋ฉ๋๋ค.
๋ ๋๊ธฐ๊ธฐ๋ก ์ธํ์ฌ ์ฒ๋ฆฌ๊ฐ ์ง์ฐ๋์ง ์์๊น?
- ํด๋น ๊ตฌ์กฐ๋ ํ๋ฆผ์์ด ์ ์ฐ์ฑ์ ๋์์ง ๋ชจ๋ฅด์ง๋ง ์ฒ๋ฆฌ๊ฐ ์ง์ฐ๋ ๊ฒ ๊ฐ๋ค๋ ์๊ฐ์ด ๋ญ๋๋ค.
- ๋๊ฐ ์๊ตฌ๋ฅผ ์ฒ๋ฆฌํ ์ง ๋ฏธ๋ฆฌ ์ ํด์ ธ ์๊ณ ๊ทธ ๋ด๋น์๊ฐ ๋ฐ๋ก ์ฒ๋ฆฌํ๋ ๊ฒฝ์ฐ์ ๋น๊ตํ๋ฉด ์ง์ฐ๋๋ ๋ถ๋ถ๋ ์์ ๊ฒ์ ๋๋ค. ๊ทธ๋ฌ๋ ์ผ์ข ์ ํธ๋ ์ด๋ ์คํ๋ก ๋ด์ผ ํฉ๋๋ค.
- ์๊ตฌ์์ ์ฒ๋ฆฌ์์ ๊ด๊ณ๊ฐ ๊ณ ์ ์ ์ด๊ณ ์ฒ๋ฆฌ ์๋๊ฐ ์๋นํ ์ค์ํ ๊ฒฝ์ฐ CoR ํจํด์ ๊ตณ์ด ์ฌ์ฉํ ์ด์ ๊ฐ ์์ ๊ฒ์ ๋๋ค.
๋ฐ์ํ
'๐บ๏ธ Design Pattern' ์นดํ ๊ณ ๋ฆฌ์ ๋ค๋ฅธ ๊ธ
[Design Pattern] Observer Pattern - ์ต์ ๋ฒ ํจํด (0) | 2024.06.09 |
---|---|
[Design Pattern] Memento Pattern - ๋ฉ๋ฉํ ํจํด (0) | 2024.06.09 |
[Design Pattern] Command Pattern - ์ปค๋งจ๋ ํจํด (0) | 2024.06.09 |
[Design Pattern] Strategy Pattern - ์ ๋ต ํจํด (0) | 2024.06.08 |
[Design Pattern] Composite Pattern - ์ปดํฌ์งํธ ํจํด (0) | 2024.06.08 |