-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathcommand_remote_control_example.dart
More file actions
128 lines (100 loc) · 3.33 KB
/
command_remote_control_example.dart
File metadata and controls
128 lines (100 loc) · 3.33 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
import 'dart:developer';
/// The definition is a bit confusing at first but let’s step through it.
/// In analogy to our problem above remote control is the client and stereo, lights etc. are the receivers.
/// In command pattern there is a Command object that encapsulates a request by binding together a set of actions on a specific receiver.\
/// It does so by exposing just one method execute() that causes some actions to be invoked on the receiver.
///
/// src: https://www.geeksforgeeks.org/command-pattern/
/// implementation of Command Pattern using
/// a remote control example.
/// An interface for command
abstract interface class Command {
void execute();
}
/// Light class (Receiver) and its corresponding command
///
/// classes
class Light {
void on() => log("Light is on");
void off() => log("Light is off");
}
class LightOnCommand implements Command {
Light light;
/// The constructor is passed the light it
/// is going to control.
LightOnCommand(this.light);
void execute() => light.on();
}
class LightOffCommand implements Command {
Light light;
/// The constructor is passed the light it
/// is going to control.
LightOffCommand(this.light);
void execute() => light.off();
}
/// Stereo (Receiver) and its command classes
class Stereo {
void on() => log("Stereo is on");
void off() => log("Stereo is off");
void setCD() => log("Stereo is set " + "for CD input");
void setDVD() => log("Stereo is set" + " for DVD input");
void setRadio() => log("Stereo is set" + " for Radio");
/// code to set the volume
void setVolume(int volume) => log("set Stereo volume to: $volume");
}
class StereoOffCommand implements Command {
Stereo stereo;
StereoOffCommand(this.stereo);
void execute() => stereo.off();
}
class StereoOnWithCDCommand implements Command {
Stereo stereo;
StereoOnWithCDCommand(this.stereo);
void execute() {
stereo.on();
stereo.setCD();
stereo.setVolume(11);
}
}
/// Invoker (Sender) A Simple remote control with one button
class SimpleRemoteControl {
/// only one button
Command? slot;
SimpleRemoteControl();
void setCommand(Command command) {
// set the command the remote will
// execute
slot = command;
}
void buttonWasPressed() {
slot?.execute();
}
}
/// Driver class
void main() {
/// Sender (Invoker)
SimpleRemoteControl remote = SimpleRemoteControl();
/// Receivers
Light light = Light();
Stereo stereo = Stereo();
/// Commands
LightOnCommand lightOnCommand = LightOnCommand(light);
StereoOnWithCDCommand stereoOnWithCDCommand = StereoOnWithCDCommand(stereo);
StereoOffCommand stereoOffCommand = StereoOffCommand(stereo);
/// we can change command dynamically
remote.setCommand(lightOnCommand);
remote.buttonWasPressed();
remote.setCommand(stereoOnWithCDCommand);
remote.buttonWasPressed();
remote.setCommand(stereoOffCommand);
remote.buttonWasPressed();
}
/// Notice that the remote control doesn’t know anything about turning on the stereo.
/// That information is contained in a separate command object.
/// This reduces the coupling between them.
/// Advantages:
/// Makes our code extensible as we can add new commands without changing existing code.
/// Reduces coupling between the invoker and receiver of a command.
///
/// Disadvantages:
/// Increase in the number of classes for each individual command