design-patterns

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

View project on GitHub

Lets you add new operations to existing classes without modifying them.

Separates an algorithm from the objects it operates on.

abstract class Shape {
  void accept(ShapeVisitor visitor);
}

class Circle implements Shape {
  final double radius;
  Circle(this.radius);

  @override
  void accept(ShapeVisitor visitor) => visitor.visitCircle(this);
}

class Square implements Shape {
  final double side;
  Square(this.side);

  @override
  void accept(ShapeVisitor visitor) => visitor.visitSquare(this);
}

abstract class ShapeVisitor {
  void visitCircle(Circle c);
  void visitSquare(Square s);
}

class AreaCalculator implements ShapeVisitor {
  @override
  void visitCircle(Circle c) => print('Circle area: ${3.14 * c.radius * c.radius}');
  @override
  void visitSquare(Square s) => print('Square area: ${s.side * s.side}');
}

// Usage
final shapes = [Circle(5), Square(4)];
final calc = AreaCalculator();
for (final s in shapes) {
  s.accept(calc);
}
// Circle area: 78.5
// Square area: 16.0