-
Notifications
You must be signed in to change notification settings - Fork 33
/
design_pattern-command.rs
102 lines (94 loc) · 2.11 KB
/
design_pattern-command.rs
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
//! Example of design pattern inspired from Head First Design Patterns
//!
//! Tested with rust-1.41.1-nightly
//!
//! @author Eliovir <http://github.com/~eliovir>
//!
//! @license MIT license <http://www.opensource.org/licenses/mit-license.php>
//!
//! @since 2014-04-20
//! Each action is encapsulated into a struct with the trait Command
//! where only the method `execute()` is run.
trait Command {
fn execute(&self);
}
// Use a Null struct to initialize the remote control.
struct NullCommand;
impl NullCommand {
fn new() -> NullCommand {
NullCommand
}
}
impl Command for NullCommand {
fn execute(&self) {
println!("Nothing to do!");
}
}
// The object to handle: a light
#[derive(Copy, Clone)]
struct Light;
impl Light {
fn new() -> Light {
Light
}
fn on(&self) {
println!("Light is on");
}
fn off(&self) {
println!("Light is off");
}
}
// The first command on the object: light on
struct LightOnCommand {
light: Light,
}
impl LightOnCommand {
fn new(light: Light) -> LightOnCommand {
LightOnCommand { light }
}
}
impl Command for LightOnCommand {
fn execute(&self) {
self.light.on();
}
}
// The second command on the object: light off
struct LightOffCommand {
light: Light,
}
impl LightOffCommand {
fn new(light: Light) -> LightOffCommand {
LightOffCommand { light }
}
}
impl Command for LightOffCommand {
fn execute(&self) {
self.light.off();
}
}
// The command will be launched by a remote control.
struct SimpleRemoteControl<'a> {
command: Box<dyn Command + 'a>,
}
impl<'a> SimpleRemoteControl<'a> {
fn new() -> SimpleRemoteControl<'a> {
SimpleRemoteControl { command: Box::new(NullCommand::new()) }
}
fn set_command(&mut self, cmd: Box<dyn Command + 'a>) {
self.command = cmd;
}
fn button_was_pressed(&self) {
self.command.execute();
}
}
fn main() {
let mut remote = SimpleRemoteControl::new();
let light = Light::new();
let light_on = LightOnCommand::new(light);
let light_off = LightOffCommand::new(light);
remote.button_was_pressed();
remote.set_command(Box::new(light_on));
remote.button_was_pressed();
remote.set_command(Box::new(light_off));
remote.button_was_pressed();
}