Decorator Pattern

Dynamically adds new behaviors or responsibilities to an object by wrapping it in a decorator class. It provides a flexible alternative to subclassing for extending functionality.

Example


// Define a trait representing the Component interface trait Beverage { fn get_description(&self) -> String; fn get_cost(&self) -> f64; } // Implementation of a concrete Component struct Coffee; impl Beverage for Coffee { fn get_description(&self) -> String { "Coffee".to_string() } fn get_cost(&self) -> f64 { 1.0 } } // Implementation of a decorator struct Milk { beverage: Box<dyn Beverage>, } impl Milk { fn new(beverage: Box<dyn Beverage>) -> Self { Milk { beverage } } } impl Beverage for Milk { fn get_description(&self) -> String { format!("{} with Milk", self.beverage.get_description()) } fn get_cost(&self) -> f64 { self.beverage.get_cost() + 0.5 } } // Implementation of another decorator struct Sugar { beverage: Box<dyn Beverage>, } impl Sugar { fn new(beverage: Box<dyn Beverage>) -> Self { Sugar { beverage } } } impl Beverage for Sugar { fn get_description(&self) -> String { format!("{} with Sugar", self.beverage.get_description()) } fn get_cost(&self) -> f64 { self.beverage.get_cost() + 0.25 } } fn main() { // Create a base component let coffee = Box::new(Coffee); // Decorate the component with Milk let coffee_with_milk = Box::new(Milk::new(coffee)); // Decorate the component with Sugar let coffee_with_milk_and_sugar = Box::new(Sugar::new(coffee_with_milk)); // Get the final description and cost of the decorated beverage println!("Description: {}", coffee_with_milk_and_sugar.get_description()); println!("Cost: ${}", coffee_with_milk_and_sugar.get_cost()); }