Monday, March 25, 2024

Proxy design pattern in Rust - my exploration continues - Karmyog is the best way forward...



Proxy pattern - as the name suggests - creates a proxy in place of a real heavy-duty object.

Let me give you a real-life example taken from computer science.

In case a document contains many huge-sized images, it does not load all the images when the doc gets loaded into the memory. Because it might take a very long time. 

The proxy pattern comes as a rescue. 

The document, instead of the actual mega images, gets loaded with very lightweight proxies of those images. And then when needed - in actual run time, i.e., when we need to see an image, the images get loaded by the proxy. This kind of proxy is called a virtual proxy.

Now let us talk from our example.

We are a family of three. Now my son does all the lightweight jobs - like, if there is a guest, he opens the door. So, he is the initial interface for the guests. However, in case, a guest wants to have lunch or dinner, my son calls his Mamma - because it's a heavy-duty job that he himself cannot do.

So basically my son gives proxy to his Mom, and if needed - like when he has to perform a heavy-duty job like cooking - he simply delegates the task to his Mom. For all other lightweight jobs, his Mom, who obviously has a lot of significant jobs to perform, remains in the background. She comes in the foreground in case there is a heavy-duty task like cooking for a guest.

Here's the UML class diagram of the proxy pattern.



Now the source code of Proxy Pattern implemented in Rust

Source Code

trait Family{

fn cook(&self);

fn open_the_door(&self){

println!("Son will handle Open The Door task");

}

}


struct Mamma{}


impl Family for Mamma {

fn cook(&self){

println!("Mamma is an expert cook..Mamma is cooking the food...");

}

}


struct Son<'a > {

mamma : & 'a Mamma,

}


impl <'a> Son<'a > {

fn new (mamma : & 'a Mamma)-> Son {

Son { mamma }

}

}


impl <'a> Family for Son<'a> {

fn cook(&self) {

println!("Son cannot cook.... So he is passing the buck to Mamma");

self.mamma.cook();

}

}


fn main() {

    let mamma : Mamma = Mamma { };

let son = Son :: new(&mamma);

son.open_the_door();

son.cook();

}


If we run the above code, the output will be like this:


Son will handle Open The Door task

Son cannot cook.... So he is passing the buck to Mamma

Mamma is an expert cook..Mamma is cooking the food...


No comments: