Skip to content

Commit e2d988f

Browse files
author
XuhuaHuang
committed
First draft of behavioural design pattern state
1 parent da7e38a commit e2d988f

1 file changed

Lines changed: 126 additions & 0 deletions

File tree

DesignPattern/state.cpp

Lines changed: 126 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,126 @@
1+
#include <iostream>
2+
#include <memory>
3+
#include <string>
4+
5+
// forward declaration
6+
class line_of_credit_t;
7+
8+
class line_of_credit_state_t {
9+
public:
10+
explicit line_of_credit_state_t(line_of_credit_t* loc)
11+
: loc(loc) {}
12+
13+
virtual ~line_of_credit_state_t() = default;
14+
15+
virtual void apply(float) {}
16+
virtual void approve() {}
17+
virtual void withdraw(float) {}
18+
virtual void make_payment(float) {}
19+
virtual void cancel() {}
20+
21+
virtual std::string name() const = 0;
22+
23+
protected:
24+
line_of_credit_t* loc;
25+
};
26+
27+
class line_of_credit_t {
28+
public:
29+
line_of_credit_t();
30+
31+
void set_state(std::unique_ptr<line_of_credit_state_t> new_state) {
32+
state = std::move(new_state);
33+
std::cout << "State changed to: " << state->name() << "\n";
34+
}
35+
36+
void apply(float amount) { state->apply(amount); }
37+
void approve() { state->approve(); }
38+
void withdraw(float amount) { state->withdraw(amount); }
39+
void make_payment(float amt) { state->make_payment(amt); }
40+
void cancel() { state->cancel(); }
41+
42+
float get_balance() const { return balance; }
43+
void set_balance(float amt) { balance = amt; }
44+
45+
private:
46+
std::unique_ptr<line_of_credit_state_t> state;
47+
48+
float balance = 0.0f;
49+
};
50+
51+
class applied_state_t : public line_of_credit_state_t {
52+
public:
53+
using line_of_credit_state_t::line_of_credit_state_t;
54+
55+
void apply(float amount) override {
56+
std::cout << "Application submitted for $" << amount << "\n";
57+
loc->set_balance(amount);
58+
}
59+
60+
void approve() override;
61+
62+
std::string name() const override { return "Applied"; }
63+
};
64+
65+
class approved_state_t : public line_of_credit_state_t {
66+
public:
67+
using line_of_credit_state_t::line_of_credit_state_t;
68+
69+
void withdraw(float amount) override;
70+
71+
std::string name() const override { return "Approved"; }
72+
};
73+
74+
class withdrawn_state_t : public line_of_credit_state_t {
75+
public:
76+
using line_of_credit_state_t::line_of_credit_state_t;
77+
78+
void make_payment(float amount) override;
79+
80+
std::string name() const override { return "Withdrawn"; }
81+
};
82+
83+
class closed_state_t : public line_of_credit_state_t {
84+
public:
85+
using line_of_credit_state_t::line_of_credit_state_t;
86+
87+
std::string name() const override { return "Closed"; }
88+
};
89+
90+
void applied_state_t::approve() {
91+
std::cout << "Credit approved\n";
92+
loc->set_state(std::make_unique<approved_state_t>(loc));
93+
}
94+
95+
void approved_state_t::withdraw(float amount) {
96+
std::cout << "Withdrawing $" << amount << "\n";
97+
loc->set_balance(loc->get_balance() - amount);
98+
loc->set_state(std::make_unique<withdrawn_state_t>(loc));
99+
}
100+
101+
void withdrawn_state_t::make_payment(float amount) {
102+
std::cout << "Payment of $" << amount << "\n";
103+
104+
float new_balance = loc->get_balance() + amount;
105+
loc->set_balance(new_balance);
106+
107+
if (new_balance >= 0) {
108+
std::cout << "Loan fully repaid\n";
109+
loc->set_state(std::make_unique<closed_state_t>(loc));
110+
}
111+
}
112+
113+
line_of_credit_t::line_of_credit_t() {
114+
state = std::make_unique<applied_state_t>(this);
115+
}
116+
117+
int main() {
118+
line_of_credit_t loc;
119+
120+
loc.apply(1000); // Applied
121+
loc.approve(); // -> Approved
122+
loc.withdraw(500); // -> Withdrawn
123+
loc.make_payment(600); // -> Closed
124+
125+
return 0;
126+
}

0 commit comments

Comments
 (0)