Skip to content

Commit

Permalink
command
Browse files Browse the repository at this point in the history
  • Loading branch information
lpxxn committed Feb 29, 2020
1 parent dcf4661 commit 81abf3b
Show file tree
Hide file tree
Showing 8 changed files with 103 additions and 28 deletions.
2 changes: 2 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,8 @@
|:-------:|:----------- |:------:|
| [Strategy](/behavioral/strategy.rs) | Enables an algorithm's behavior to be selected at runtime ||
| [State](/behavioral/state.rs) | Encapsulates varying behavior for the same object based on its internal state ||
| [Command](/behavioral/command.rs) | Bundles a command and arguments to call later ||



## Structural Patterns
Expand Down
87 changes: 87 additions & 0 deletions behavioral/command.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,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);
}
14 changes: 7 additions & 7 deletions behavioral/state.rs
Original file line number Diff line number Diff line change
@@ -1,11 +1,11 @@
// State is a behavioral design pattern that lets an object alter its behavior when its internal state changes.
// It appears as if the object changed its class.
//! State is a behavioral design pattern that lets an object alter its behavior when its internal state changes.
//! It appears as if the object changed its class.

// We’ll implement a blog post workflow
// 1. A blog post starts as an empty draft.
// 2. When the draft is done, a review of the post is requested.
// 3. When the post is approved, it gets published.
// 4. Only published blog posts return content to print, so unapproved posts can’t accidentally be published.
//! We’ll implement a blog post workflow
//! 1. A blog post starts as an empty draft.
//! 2. When the draft is done, a review of the post is requested.
//! 3. When the post is approved, it gets published.
//! 4. Only published blog posts return content to print, so unapproved posts can’t accidentally be published.

trait State {
fn request_review(self: Box<Self>) -> Box<dyn State>;
Expand Down
4 changes: 1 addition & 3 deletions creational/abstract_factory.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,4 @@
/*
Abstract Factory is a creational design pattern that lets you produce families of related objects without specifying their concrete classes.
*/
//! Abstract Factory is a creational design pattern that lets you produce families of related objects without specifying their concrete classes.

trait GUIFactory {
fn create_button(&self) -> Box<dyn Button>;
Expand Down
9 changes: 2 additions & 7 deletions creational/builder.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
/*
Builder is a creational design pattern, which allows constructing complex objects step by step.
*/
//! Builder is a creational design pattern, which allows constructing complex objects step by step.

#[derive(Clone)]
struct Product {
parts: Vec<String>,
Expand Down Expand Up @@ -60,10 +59,6 @@ impl Builder for ContreteBuilder1 {
}
fn get_product(&mut self) -> Product {
let p = self.product.clone();
// Product {
// parts: self.product.parts.clone(),
// ..self.product
// };
self.product = Product::new();

This comment has been minimized.

Copy link
@wangshankun

wangshankun Dec 24, 2020

为什么不用引用返回呢? clone多了次深度复制

p
}
Expand Down
4 changes: 1 addition & 3 deletions creational/factory.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,4 @@
/*
Factory method creational design pattern allows creating objects without having to specify the exact type of the object that will be created.
*/
//! Factory method creational design pattern allows creating objects without having to specify the exact type of the object that will be created.

trait Shape {
fn draw(&self);
Expand Down
2 changes: 1 addition & 1 deletion creational/singleton.rs
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ fn get_config() -> Arc<Mutex<Config>> {
fn main() {
let f1 = get_config();
println!("{:?}", f1);
// modify
// modify
{
let mut conf = f1.lock().unwrap();
conf.db_connection_str = "hello".to_string();
Expand Down
9 changes: 2 additions & 7 deletions structural/decorator.rs
Original file line number Diff line number Diff line change
Expand Up @@ -33,9 +33,7 @@ struct ConcreteDecoratorA {

impl Decorator for ConcreteDecoratorA {
fn new(component: Rc<dyn Component>) -> Self {
ConcreteDecoratorA {
component,
}
ConcreteDecoratorA { component }
}
}

Expand All @@ -51,9 +49,7 @@ struct ConcreteDecoratorB {

impl Decorator for ConcreteDecoratorB {
fn new(component: Rc<dyn Component>) -> Self {
ConcreteDecoratorB {
component,
}
ConcreteDecoratorB { component }
}
}

Expand Down Expand Up @@ -84,5 +80,4 @@ fn main() {

let decorator_a2 = ConcreteDecoratorB::new(Rc::new(decorator_a1));
Client::client_code(&decorator_a2);

}

0 comments on commit 81abf3b

Please sign in to comment.