-
Notifications
You must be signed in to change notification settings - Fork 1
Expand file tree
/
Copy pathStatePattern.js
More file actions
178 lines (143 loc) · 3.47 KB
/
Copy pathStatePattern.js
File metadata and controls
178 lines (143 loc) · 3.47 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
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
"use strict";
/**
* State Pattern - Allows an object to change its behaviour when its internal state
* changes. The object will seem to change its class as well.
*
* Example - A candy dispenser is commonly found in shopping malls. This machine
* takes in coin as an input and delivers candy as the output. There are states
* involved in this process, hasCoin, noCoin, hasCandy and noCandy states.
* Each state implements the same set of methods but uses a different algorithm
* to fit its use case.
*
*/
class CandyDispenser {
constructor() {
this.hasCoin = new HasCoin(this);
this.noCoin = new NoCoin(this);
this.hasCandy = new HasCandy(this);
this.noCandy = new NoCandy(this);
this.state = this.noCoin;
this.candyCount = 1;
}
getHasCoin() {
return this.hasCoin;
}
getNoCoin() {
return this.noCoin;
}
getHasCandy() {
return this.hasCandy;
}
getNoCandy() {
return this.noCandy;
}
setState(state) {
this.state = state;
}
dispense() {
this.state.dispense();
}
insertCoin() {
this.state.insertCoin();
}
ejectCoin() {
this.state.ejectCoin();
}
turnKnob() {
this.state.turnKnob();
}
}
class State {
constructor(dispenser) {
this.dispenser = dispenser;
}
dispense() {
console.log("You need to implement this method");
}
insertCoin() {
console.log("You need to implement this method");
}
ejectCoin() {
console.log("You need to implement this method");
}
turnKnob() {
console.log("You need to implement this method");
}
}
class HasCoin extends State {
dispense() {
console.log("Nothing happens");
}
insertCoin() {
console.log("You have already got a coin inside");
}
ejectCoin() {
console.log("The machine returns you back your coin");
this.dispenser.setState(this.dispenser.getNoCoin());
}
turnKnob() {
console.log("Checking if the machine still have any candies left");
if (this.dispenser.candyCount > 0) {
this.dispenser.setState(this.dispenser.getHasCandy());
} else {
this.dispenser.setState(this.dispenser.getNoCandy());
}
this.dispenser.dispense();
}
}
class NoCoin extends State {
dispense() {
console.log("Nothing happens");
}
insertCoin() {
console.log("You inserted a coin");
this.dispenser.setState(this.dispenser.getHasCoin());
}
ejectCoin() {
console.log("There is no coin for you to eject");
}
turnKnob() {
console.log("Please don't try to cheat the system");
}
}
class HasCandy extends State {
dispense() {
console.log("One candy drop out");
this.dispenser.candyCount = this.dispenser.candyCount - 1;
console.log(`Candies left: ${this.dispenser.candyCount}`);
this.dispenser.setState(this.dispenser.getNoCoin());
}
insertCoin() {
console.log("Eating your coin, please wait");
}
ejectCoin() {
console.log("Sorry too late, eating your coin now");
}
turnKnob() {
console.log("You can't dispense twice!");
}
}
class NoCandy extends State {
dispense() {
console.log("No more candy left, sorry");
this.dispenser.setState(this.dispenser.getHasCoin());
}
insertCoin() {
console.log("Your coin is still inside");
}
ejectCoin() {
console.log("The machine returns you back your coin");
this.dispenser.setState(this.dispenser.getNoCoin());
}
turnKnob() {
console.log("You can't turn the knob yet!");
}
}
var candyDispenser = new CandyDispenser();
candyDispenser.insertCoin();
candyDispenser.insertCoin();
candyDispenser.turnKnob();
candyDispenser.ejectCoin();
candyDispenser.insertCoin();
candyDispenser.turnKnob();
candyDispenser.ejectCoin();