design-patterns

Quick-reference guide to software design patterns with concise Dart examples.

View project on GitHub

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