CODESAMPLE
Adapter - Rust
The Adapter pattern converts the interface of a class into another interface clients expect. This allows classes with incompatible interfaces to work together. Here, we adapt a CelsiusTemperature struct (legacy system) to be usable with functions expecting FahrenheitTemperature. We define a CelsiusToFahrenheitAdapter which implements the FahrenheitTemperature trait by internally holding a CelsiusTemperature instance and converting on demand. This adheres to Rust’s strong typing and trait-based polymorphism, providing a clean and type-safe way to integrate differing interfaces without modifying the original CelsiusTemperature struct.
// Legacy system: Celsius temperature representation
struct CelsiusTemperature {
temperature: f64,
}
impl CelsiusTemperature {
fn new(temp: f64) -> Self {
CelsiusTemperature { temperature: temp }
}
fn get_celsius(&self) -> f64 {
self.temperature
}
}
// Target interface: Fahrenheit temperature representation
trait FahrenheitTemperature {
fn get_fahrenheit(&self) -> f64;
}
// Adapter: Converts Celsius to Fahrenheit
struct CelsiusToFahrenheitAdapter {
celsius: CelsiusTemperature,
}
impl CelsiusToFahrenheitAdapter {
fn new(celsius: CelsiusTemperature) -> Self {
CelsiusToFahrenheitAdapter { celsius }
}
}
impl FahrenheitTemperature for CelsiusToFahrenheitAdapter {
fn get_fahrenheit(&self) -> f64 {
(self.celsius.get_celsius() * 9.0 / 5.0) + 32.0
}
}
// Client code expecting Fahrenheit
fn print_temperature_fahrenheit(temp: &dyn FahrenheitTemperature) {
println!("Temperature in Fahrenheit: {}", temp.get_fahrenheit());
}
fn main() {
let celsius_temp = CelsiusTemperature::new(25.0);
// Use the adapter to work with the Celsius temperature
let fahrenheit_adapter = CelsiusToFahrenheitAdapter::new(celsius_temp);
print_temperature_fahrenheit(&fahrenheit_adapter);
}