-
Notifications
You must be signed in to change notification settings - Fork 5
Expand file tree
/
Copy pathchain_of_responsibility.cpp
More file actions
97 lines (82 loc) · 2.68 KB
/
chain_of_responsibility.cpp
File metadata and controls
97 lines (82 loc) · 2.68 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
// Chain of responsibility design pattern
#include <cstddef>
#include <iomanip>
#include <iostream>
#include <memory>
// handler interface
class IHandler {
std::shared_ptr<IHandler> next_{nullptr};
public:
void set_next(std::shared_ptr<IHandler> handler) { next_ = handler; }
std::shared_ptr<IHandler> get_next() const { return next_; }
virtual void handle_request(std::size_t ammount) = 0;
virtual ~IHandler() = default;
};
// client
class ATM {
std::shared_ptr<IHandler> start_;
public:
ATM(std::shared_ptr<IHandler> start) : start_{start} {}
void set_start(std::shared_ptr<IHandler> start) { start_ = start; }
void dispense(std::size_t ammount) {
std::cout << "ATM withdrawal of $" << ammount << '\n';
start_->handle_request(ammount);
}
};
// concrete handlers
class Handle_100 : public IHandler {
void handle_request(std::size_t ammount) override {
std::size_t q = ammount / 100;
std::size_t r = ammount % 100;
if (q > 0) {
std::cout << "Dispensing: ";
std::cout << std::right << std::setw(10) << q << " x $100\n";
get_next()->handle_request(r);
} else {
get_next()->handle_request(ammount);
}
}
};
struct Handle_50 : public IHandler {
void handle_request(std::size_t ammount) override {
std::size_t q = ammount / 50;
std::size_t r = ammount % 50;
if (q > 0) {
std::cout << "Dispensing: ";
std::cout << std::right << std::setw(10) << q << " x $50\n";
get_next()->handle_request(r);
} else {
get_next()->handle_request(ammount);
}
}
};
struct Handle_20 : public IHandler {
void handle_request(std::size_t ammount) override {
std::size_t q = ammount / 20;
std::size_t r = ammount % 20;
if (q > 0) {
std::cout << "Dispensing: ";
std::cout << std::right << std::setw(10) << q << " x $20\n";
}
if (r > 0) {
std::cout << "Dispensing change: ";
std::cout << std::right << std::setw(3) << r << " x $1\n";
}
}
};
int main() {
// define the chain elements
auto handle_100 = std::make_shared<Handle_100>();
auto handle_50 = std::make_shared<Handle_50>();
auto handle_20 = std::make_shared<Handle_20>();
// link the chain elements
handle_100->set_next(handle_50);
handle_50->set_next(handle_20);
// instantiate the ATM with the beginning of the chain
ATM atm{handle_100};
atm.dispense(1296);
std::cout << '\n';
// instantiate the ATM with $50 handler as the starting of the chain
atm.set_start(handle_50);
atm.dispense(443);
}