forked from lpxxn/rust-design-pattern
-
Notifications
You must be signed in to change notification settings - Fork 0
/
command.rs
87 lines (73 loc) · 1.6 KB
/
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
//! Each action is encapsulated into a struct with the trait Command
use std::collections::HashMap;
trait Command {
fn execute(&self);
}
#[derive(Copy, Clone)]
struct TV;
impl TV {
fn new() -> TV {
TV
}
fn on(&self) {
println!("TV is on, watch movies.");
}
fn off(&self) {
println!("TV is off");
}
}
struct TVOnCommand {
tv: TV,
}
impl TVOnCommand {
fn new(tv: TV) -> TVOnCommand {
TVOnCommand { tv }
}
}
impl Command for TVOnCommand {
fn execute(&self) {
self.tv.on();
}
}
struct TVOffCommand {
tv: TV,
}
impl TVOffCommand {
fn new(tv: TV) -> TVOffCommand {
TVOffCommand { tv }
}
}
impl Command for TVOffCommand {
fn execute(&self) {
self.tv.off();
}
}
struct TVRemoteControl {
commands: HashMap<i32, Box<dyn Command>>,
}
impl TVRemoteControl {
fn new() -> TVRemoteControl {
TVRemoteControl {
commands: HashMap::new(),
}
}
fn set_command(&mut self, idx: i32, cmd: Box<dyn Command>) {
self.commands.insert(idx, cmd);
}
fn press_button(&self, idx: i32) {
if let Some(cmd) = self.commands.get(&idx) {
cmd.execute();
} else {
println!("do nothing.");
}
}
}
fn main() {
let tv = TV::new();
let mut remote_control = TVRemoteControl::new();
remote_control.press_button(0);
remote_control.set_command(1, Box::new(TVOnCommand::new(tv)));
remote_control.set_command(2, Box::new(TVOffCommand::new(tv)));
remote_control.press_button(1);
remote_control.press_button(2);
}