Thursday, March 28, 2024

Strategy Design Pattern in Rust...


Karmyog - Work is worship...

In Rust, i keep my Trust...

The strategy design pattern is a behavioral design pattern that lets you dynamically switch the behavior of an object at runtime. It achieves this by separating the core functionality of the object from the specific algorithms it uses.

Here's a breakdown of the core concepts:

Strategy Interface: This interface defines the common operation that all the different algorithms will implement. This ensures that all the interchangeable strategies can be used by the context object.

Concrete Strategies: These are the classes that implement the specific algorithms. Each concrete strategy class implements the strategy interface and provides its own unique behavior for the operation.

Context Object: This object holds a reference to a strategy object and delegates the specific operation to it. It can change its behavior at runtime by switching the reference to a different concrete strategy.

Here's an example of an UML diagram for the Strategy Design Pattern.



In my code, the 

trait TransportationToAirport{

fn going_to_the_airport(&self);

}

plays the role of the Strategy interface.

Three concrete Strategy classes have been derived from this interface  - namely, By_Ola, By_Bus and By_Rapido.

These concrete strategy classes help to pick up a specific way for going to the airport dynamically, i.e.,  in runtime.

Here's the source code for Strategy Pattern implemented in Rust.

use std::io;


trait TransportationToAirport{

fn going_to_the_airport(&self);

}


struct By_Bus{}


impl TransportationToAirport for By_Bus {

fn going_to_the_airport(&self) {

println!("Going to airport by Bus...");

}

}


struct By_Ola{}



impl TransportationToAirport for By_Ola{

fn going_to_the_airport(&self) {

println!("Going to airport by Ola...")

}

}


struct By_Rapido{}


impl TransportationToAirport for By_Rapido{

fn going_to_the_airport(&self) {

println!("Going to airport by Rapido...");

}

}



struct Traveller{

strategy : Box<dyn TransportationToAirport>,

}


impl Traveller{

fn new(strategy: Box<dyn TransportationToAirport>) -> Self {

Traveller { strategy }

}

fn travel(&self){

self.strategy.going_to_the_airport();

}

pub fn set_strategy(&mut self, strategy: Box<dyn TransportationToAirport>) {

self.strategy = strategy;

}

}



fn main() {

println!("Enter your choice...");

let mut choice = String::new();

io::stdin().read_line(&mut choice);

if choice.trim().eq("BUS".trim()){

let traveller : Traveller = Traveller::new(Box::new(By_Bus{}));

traveller.travel();

}

if choice.trim().eq("OLA".trim()){

let traveller : Traveller = Traveller::new(Box::new(By_Ola{}));

traveller.travel();

}

if choice.trim().eq("RAPIDO".trim()){

let traveller : Traveller = Traveller::new(Box::new(By_Rapido{}));

traveller.travel();

}

}

Here's the output of the above code:

Enter your choice...

OLA

Going to airport by Ola...

No comments: