Skip to content

Commit

Permalink
command patter
Browse files Browse the repository at this point in the history
  • Loading branch information
saltukalakus committed Nov 26, 2024
1 parent 6c7bc7a commit b3090bb
Show file tree
Hide file tree
Showing 11 changed files with 155 additions and 2 deletions.
3 changes: 2 additions & 1 deletion src/SUMMARY.md
Original file line number Diff line number Diff line change
Expand Up @@ -48,4 +48,5 @@
- [Patterns](./patterns/intro.md)
- [Behavioral](./patterns/behavioral/intro.md)
- [Observer](./patterns/behavioral/observer.md)
- [Strategy](./patterns/behavioral/strategy.md)
- [Strategy](./patterns/behavioral/strategy.md)
- [Command](./patterns/behavioral/command.md)
Binary file added src/patterns/.DS_Store
Binary file not shown.
46 changes: 46 additions & 0 deletions src/patterns/behavioral/command.md
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).
7 changes: 7 additions & 0 deletions src/patterns/behavioral/command/Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

6 changes: 6 additions & 0 deletions src/patterns/behavioral/command/Cargo.toml
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]
3 changes: 3 additions & 0 deletions src/patterns/behavioral/command/src/command.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
pub trait Command {
fn execute(&mut self);
}
24 changes: 24 additions & 0 deletions src/patterns/behavioral/command/src/concrete_command.rs
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();
}
}
19 changes: 19 additions & 0 deletions src/patterns/behavioral/command/src/light.rs
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");
}
}
26 changes: 26 additions & 0 deletions src/patterns/behavioral/command/src/main.rs
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();
}
}
21 changes: 21 additions & 0 deletions src/patterns/behavioral/command/src/remote_control.rs
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();
}
}
}
2 changes: 1 addition & 1 deletion src/patterns/behavioral/intro.md
Original file line number Diff line number Diff line change
Expand Up @@ -8,4 +8,4 @@ Behavioral Patterns deal with object collaboration and the delegation of respons

2- [Strategy](./strategy.md): Defines a family of algorithms, encapsulates each one, and makes them interchangeable.

3- Command: Encapsulates a request as an object, thereby allowing for parameterization of clients with queues, requests, and operations.
3- [Command](./command.md): Encapsulates a request as an object, thereby allowing for parameterization of clients with queues, requests, and operations.

0 comments on commit b3090bb

Please sign in to comment.