Repository navigation
Expand file tree
/
Copy path1-theory.ts
More file actions
129 lines (104 loc) · 3.23 KB
/
Copy path1-theory.ts
File metadata and controls
129 lines (104 loc) · 3.23 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
abstract class OrderState {
protected context: TaxiOrderContext;
constructor(context: TaxiOrderContext) {
this.context = context;
}
cancel(reason: string): void {
console.log('Action is not allowed in the current state.');
}
pay(amount: number): void {
console.log('Action is not allowed in the current state.');
}
message(text: string): void {
console.log('Action is not allowed in the current state.');
}
}
class OrderCanceledState extends OrderState {
cancel(reason: string): void {
console.log('The order is already canceled.');
}
}
class OrderPaidState extends OrderState {
cancel(reason: string): void {
console.log('Order canceled. The money will be returned.');
}
message(text: string): void {
console.log('Your message has been sent.');
}
}
class SearchingDriverState extends OrderState {
cancel(reason: string): void {
console.log('Order canceled. No driver was assigned.');
this.context.setState(new OrderCanceledState(this.context));
}
pay(amount: number): void {
console.log('You cannot pay before the car is found.');
}
message(text: string): void {
console.log('You cannot message before the car is found.');
}
}
class DriverAssignedState extends OrderState {
cancel(reason: string): void {
console.log('Order canceled. Informing the driver.');
this.context.setState(new OrderCanceledState(this.context));
}
pay(amount: number): void {
console.log(`Payment ${amount} processed. Thank you!`);
this.context.setState(new OrderPaidState(this.context));
}
message(text: string): void {
console.log('Driver assigned. Your message has been sent.');
}
}
class RideInProgressState extends OrderState {
cancel(reason: string): void {
console.log('You cannot cancel the ride while in progress.');
}
}
class RideCompletedState extends OrderState {
cancel(reason: string): void {
console.log('You cannot cancel the ride after completion.');
}
}
class TaxiOrderContext {
private state: OrderState;
constructor() {
this.state = new SearchingDriverState(this);
}
setState(state: OrderState): void {
this.state = state;
}
cancel(reason: string): void {
const state = Object.getPrototypeOf(this.state).constructor.name;
console.log(`State: ${state}, Cancel: ${reason}`);
this.state.cancel(reason);
}
pay(amount: number): void {
const state = Object.getPrototypeOf(this.state).constructor.name;
console.log(`State: ${state}, Pay: ${amount}`);
this.state.pay(amount);
}
message(text: string): void {
const state = Object.getPrototypeOf(this.state).constructor.name;
console.log(`State: ${state}, Message: ${text}`);
this.state.message(text);
}
}
// Usage
const order = new TaxiOrderContext();
order.message('Hello');
order.cancel('I changed plans');
const newOrder = new TaxiOrderContext();
newOrder.message('Hello');
newOrder.setState(new DriverAssignedState(newOrder));
newOrder.message('Waiting...');
newOrder.cancel('No longer needed');
const ride = new TaxiOrderContext();
ride.setState(new RideInProgressState(ride));
ride.message('Hello');
ride.pay(50);
ride.cancel('Return my money');
ride.setState(new RideCompletedState(ride));
ride.pay(50);
ride.cancel('Return my money');