책임 연쇄 패턴이란?
- 여러 개의 객체(Handler)를 체인 형태로 연결하여, 요청(Request)이 처리될 때까지 차례대로 전달하는 패턴
- 요청을 보낼 클라이언트(Caller)와 처리 객체(Handler)를 분리하여 유연성 높임
- 특정 핸들러(Handler)가 요청을 처리할 수 없으면 다음 핸들러로 전달
구성 요소
1. Handler (추상 핸들러)
요청을 처리할 수 있는 공통 인터페이스
다음 핸들러를 저장하고, 요청을 넘기는 기능을 제공
2. Concrete Handler(구체적인 핸들러)
Handler를 상속받아 실제 요청을 처리하는 클래스
요청을 처리할 수 있으면 처리하고, 못하면 다음 핸들러에게 전달
3. Client (클라이언트)
요청을 보낼 객체
첫 번째 핸들러에 요청을 전달하고, 필요하면 체인에서 다음 핸들러로 이동
패턴 흐름
1. 클라이언트가 요청을 첫 번째 Handler 에게 전달
2. 현재 Handler가 요청을 처리할 수 있으면 처리하고 종료
3. 처리할 수 없으면 다음 Handler로 요청 넘김
4. 마지막 Handler까지 요청이 전달되었는데도 처리할 수 없다면 요청은 무시되거나 예외 처리
책임 연쇄 패턴 예제 (C++)
1. #include <iostream>
2. #include <memory>
3. #include <string>
4.
5. using namespace std;
6.
7. // 1. Handler (추상 핸들러)
8. class Approver {
9. protected:
10. shared_ptr<Approver> nextApprover; // 다음 핸들러
11.
12. public:
13. virtual ~Approver() {}
14. void setNext(shared_ptr<Approver> next) { nextApprover = next; }
15.
16. virtual void processRequest(int amount) = 0;
17. };
18.
19. // 2. ConcreteHandler (구체적인 핸들러) - 직원
20. class Employee : public Approver {
21. public:
22. void processRequest(int amount) override {
23. if (amount <= 1000) {
24. cout << "Employee: " << amount << "$ 승인 완료" << endl;
25. } else if (nextApprover) {
26. cout << "Employee: 승인 불가 → 매니저에게 전달..." << endl;
27. nextApprover->processRequest(amount);
28. }
29. }
30. };
31.
32. // 3. ConcreteHandler (구체적인 핸들러) - 매니저
33. class Manager : public Approver {
34. public:
35. void processRequest(int amount) override {
36. if (amount <= 5000) {
37. cout << "Manager: " << amount << "$ 승인 완료" << endl;
38. } else if (nextApprover) {
39. cout << "Manager: 승인 불가 → CEO에게 전달..." << endl;
40. nextApprover->processRequest(amount);
41. }
42. }
43. };
44.
45. // 4. ConcreteHandler (구체적인 핸들러) - CEO
46. class CEO : public Approver {
47. public:
48. void processRequest(int amount) override {
49. if (amount <= 10000) {
50. cout << "CEO: " << amount << "$ 승인 완료" << endl;
51. } else {
52. cout << "CEO: 승인 불가 (요청 거절)" << endl;
53. }
54. }
55. };
56.
57. // 5. Client (클라이언트)
58. int main() {
59. // 핸들러 체인 설정
60. shared_ptr<Approver> employee = make_shared<Employee>();
61. shared_ptr<Approver> manager = make_shared<Manager>();
62. shared_ptr<Approver> ceo = make_shared<CEO>();
63.
64. employee->setNext(manager);
65. manager->setNext(ceo);
66.
67. // 요청 처리
68. cout << "🔹 800$ 요청\n";
69. employee->processRequest(800);
70.
71. cout << "\n🔹 3000$ 요청\n";
72. employee->processRequest(3000);
73.
74. cout << "\n🔹 7000$ 요청\n";
75. employee->processRequest(7000);
76.
77. cout << "\n🔹 12000$ 요청\n";
78. employee->processRequest(12000);
79.
80. return 0;
81. }
82.
책임 연쇄 패턴 장점
1. 요청을 보낼 객체(클라이언트)와 처리 객체(핸들러)를 분리할 수 있음
2. 핸들러 추가, 제거, 수정이 클라이언트 코드에 영향을 주지 않음 : 유연하고 확장성이 뛰어남
3. 런타임에 핸들러의 연결 구조를 변경할 수 있어 객체 간의 결합도를 낮춤
책임 연쇄 패턴 단점
1. 어떤 핸들러가 요청을 처리할 지 예측하지 어려움
2. 모든 요청이 반드시 처리된다는 보장이 없음
'Unity > 디자인 패턴' 카테고리의 다른 글
| 디자인 패턴 (행위 패턴) - 메멘토 패턴 (Memento Pattern) (0) | 2025.08.30 |
|---|---|
| 디자인 패턴 (행위 패턴) - 미디에이터 패턴 (Mediator Pattern) (0) | 2025.08.30 |
| 디자인 패턴 (행위 패턴) - 템플릿 메서드 패턴 (Template Method Pattern) (0) | 2025.08.30 |
| 디자인 패턴 (행위 패턴) - 전략 패턴 (Strategy Pattern) (0) | 2025.08.30 |
| 디자인 패턴 (행위 패턴) - 상태 패턴 (State Pattern) (0) | 2025.08.30 |