Attaches additional behavior to an object dynamically without modifying its class.
An alternative to subclassing for extending functionality.
abstract class Coffee {
String get description;
double get cost;
}
class PlainCoffee implements Coffee {
@override
String get description => 'Plain coffee';
@override
double get cost => 2.0;
}
class MilkDecorator implements Coffee {
final Coffee _coffee;
MilkDecorator(this._coffee);
@override
String get description => '${_coffee.description} + milk';
@override
double get cost => _coffee.cost + 0.5;
}
class SugarDecorator implements Coffee {
final Coffee _coffee;
SugarDecorator(this._coffee);
@override
String get description => '${_coffee.description} + sugar';
@override
double get cost => _coffee.cost + 0.25;
}
// Usage
Coffee order = PlainCoffee();
order = MilkDecorator(order);
order = SugarDecorator(order);
print('${order.description}: \$${order.cost}'); // Plain coffee + milk + sugar: $2.75