-
Notifications
You must be signed in to change notification settings - Fork 1
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
1 parent
6c7bc7a
commit b3090bb
Showing
11 changed files
with
155 additions
and
2 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Binary file not shown.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,46 @@ | ||
### Command Design Pattern in Rust | ||
|
||
The Command Design Pattern is a behavioral design pattern that turns a request into a stand-alone object that contains all information about the request. This transformation allows for parameterization of methods with different requests, queuing of requests, and logging of the requests. It also provides support for undoable operations. | ||
|
||
### Components of Command Pattern | ||
|
||
1. **Command**: Declares an interface for executing an operation. | ||
2. **ConcreteCommand**: Implements the Command interface and defines a binding between a Receiver object and an action. | ||
3. **Client**: Creates a ConcreteCommand object and sets its receiver. | ||
4. **Invoker**: Asks the command to carry out the request. | ||
5. **Receiver**: Knows how to perform the operations associated with carrying out a request. | ||
|
||
#### Example in Rust | ||
|
||
Below is an example of the Command Design Pattern implemented in Rust: | ||
|
||
|
||
```rust,noplaypen | ||
{{#include command/src/command.rs}} | ||
``` | ||
|
||
```rust,noplaypen | ||
{{#include command/src/concrete_command.rs}} | ||
``` | ||
|
||
```rust,noplaypen | ||
{{#include command/src/light.rs}} | ||
``` | ||
|
||
```rust,noplaypen | ||
{{#include command/src/remote_control.rs}} | ||
``` | ||
|
||
```rust,noplaypen | ||
{{#include command/src/main.rs}} | ||
``` | ||
|
||
In this example: | ||
- `Command` is a trait that declares the `execute` method. | ||
- `Light` is the receiver that knows how to perform the operations. | ||
- `TurnOnCommand` and `TurnOffCommand` are concrete commands that implement the `Command` trait. | ||
- `RemoteControl` is the invoker that triggers the commands. | ||
|
||
This pattern decouples the object that invokes the operation from the one that knows how to perform it. | ||
|
||
You may find the sample project [here](https://github.com/saltukalakus/idiomatic-rust-snippets/tree/main/src/patterns/behavioral/command). |
Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.
Oops, something went wrong.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,6 @@ | ||
[package] | ||
name = "command_pattern" | ||
version = "0.1.0" | ||
edition = "2018" | ||
|
||
[dependencies] |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,3 @@ | ||
pub trait Command { | ||
fn execute(&mut self); | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,24 @@ | ||
use crate::light::Light; | ||
use crate::command::Command; | ||
|
||
|
||
pub struct TurnOnCommand<'a> { | ||
pub light: &'a mut Light, | ||
} | ||
|
||
impl<'a> Command for TurnOnCommand<'a> { | ||
fn execute(&mut self) { | ||
self.light.turn_on(); | ||
} | ||
} | ||
|
||
// ConcreteCommand for turning off the light | ||
pub struct TurnOffCommand<'a> { | ||
pub light: &'a mut Light, | ||
} | ||
|
||
impl<'a> Command for TurnOffCommand<'a> { | ||
fn execute(&mut self) { | ||
self.light.turn_off(); | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,19 @@ | ||
pub struct Light { | ||
is_on: bool, | ||
} | ||
|
||
impl Light { | ||
pub fn new() -> Self { | ||
Light { is_on: false } | ||
} | ||
|
||
pub fn turn_on(&mut self) { | ||
self.is_on = true; | ||
println!("The light is on"); | ||
} | ||
|
||
pub fn turn_off(&mut self) { | ||
self.is_on = false; | ||
println!("The light is off"); | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,26 @@ | ||
mod command; | ||
mod concrete_command; | ||
mod light; | ||
mod remote_control; | ||
|
||
use concrete_command::TurnOnCommand; | ||
use concrete_command::TurnOffCommand; | ||
use remote_control::RemoteControl; | ||
use light::Light; | ||
|
||
fn main() { | ||
let mut light = Light::new(); | ||
{ | ||
let turn_on_command = TurnOnCommand { light: &mut light }; | ||
let mut remote = RemoteControl::new(); | ||
remote.set_command(Box::new(turn_on_command)); | ||
remote.press_button(); | ||
} | ||
|
||
{ | ||
let turn_off_command = TurnOffCommand { light: &mut light }; | ||
let mut remote = RemoteControl::new(); | ||
remote.set_command(Box::new(turn_off_command)); | ||
remote.press_button(); | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,21 @@ | ||
use crate::command::Command; | ||
|
||
pub struct RemoteControl<'a> { | ||
command: Option<Box<dyn Command + 'a>>, | ||
} | ||
|
||
impl<'a> RemoteControl<'a> { | ||
pub fn new() -> Self { | ||
RemoteControl { command: None } | ||
} | ||
|
||
pub fn set_command(&mut self, command: Box<dyn Command + 'a>) { | ||
self.command = Some(command); | ||
} | ||
|
||
pub fn press_button(&mut self) { | ||
if let Some(ref mut command) = self.command { | ||
command.execute(); | ||
} | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters