Course contentsShow
← Rust
Lesson 622 of 1,9105. Type System and TraitsFree lesson

The Proxy Pattern for Lazy Initialization

Wrap resources in proxy types that implement standard traits for deferred load.

In this lesson, you will learn how to use the Proxy Pattern to defer the loading of expensive resources until they are strictly necessary, saving memory and startup time.

The Problem: Costly Initialization

Sometimes, an object takes a long time to construct—perhaps it requires heavy file I/O or a network connection. If you create this object globally or at application startup, you might waste resources if the object is never actually used during a specific execution path.

The Solution: The Proxy Pattern

Instead of storing the heavy resource directly, we store a "Proxy" that holds the capability to load that resource. By implementing a standard trait on this Proxy, we can treat it exactly like the real object, while hiding the "lazy" initialization logic inside our method calls.

Consider this example where we have a HeavyData struct:

trait DataProvider {
    fn get_value(&mut self) -> &str;
}

struct LazyProxy {
    inner: Option<String>,
}

impl DataProvider for LazyProxy {
    fn get_value(&mut self) -> &str {
        // Initialization happens only when requested
        self.inner.get_or_insert_with(|| {
            println!("Performing expensive loading...");
            "Result from disk".to_string()
        })
    }
}

Why Use This in Rust?

By wrapping the resource in a struct that implements a trait, the rest of your application doesn't need to know if the data was pre-loaded or loaded on-demand. This is a form of abstraction that keeps your business logic clean. You gain performance efficiency without changing the public interface of your components.

Because we are using Option and the trait system, we ensure that the heavy resource is only allocated once (via get_or_insert_with) and is protected by the type system. You aren't just saving CPU cycles; you are enforcing a design where expensive operations have an explicit, controlled entry point.

Key Takeaway: The Proxy Pattern allows you to swap a concrete, expensive resource for a lightweight handle that implements the same trait, deferring initialization until the exact moment of first use.