Adapter Design Pattern

The Adapter pattern allows incompatible interfaces to work together. This is useful when you want to use a class that doesn't have the exact interface you need.

// The existing interface that we want to adapt
trait Target {
    fn request(&self) -> String;
}

// The adaptee class with a different interface
struct Adaptee;

impl Adaptee {
    fn specific_request(&self) -> String {
        "specific request".to_string()
    }
}

// The adapter class that makes Adaptee compatible with Target
struct Adapter {
    adaptee: Adaptee,
}

impl Adapter {
    fn new(adaptee: Adaptee) -> Self {
        Adapter { adaptee }
    }
}

impl Target for Adapter {
    fn request(&self) -> String {
        // Translate the interface of Adaptee to the Target interface
        self.adaptee.specific_request()
    }
}

fn main() {
    let adaptee = Adaptee;
    let adapter = Adapter::new(adaptee);

    // Client code can use the adapter as if it were a Target
    println!("Adapter request: {}", adapter.request());
}
  1. Target Trait: Defines the interface that the client expects.
  2. Adaptee Struct: The existing class with a different interface that needs to be adapted.
  3. Adapter Struct: Implements the Target trait and translates the interface of Adaptee to the Target interface.
  4. main() Function: Demonstrates the usage of the adapter to make Adaptee compatible with the Target interface.

This example shows how the Adapter pattern can be used to make two incompatible interfaces work together.