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<'a> {
        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...

0
Subscribe to my newsletter

Read articles from Somenath Mukhopadhyay directly inside your inbox. Subscribe to the newsletter, and don't miss out.

Written by

Somenath Mukhopadhyay
Somenath Mukhopadhyay

To win is no more than this... To rise each time you fall...