Design patterns
patterns23VisitorPattern
- Path
- pkg8patterns/patterns23VisitorPattern.java
- Package
- pkg8patterns
- Study order
- 23
- Run
- Single-file source launch
- Command
- java pkg8patterns/patterns23VisitorPattern.java
There is no in-browser runner. This is the file from the curriculum, unchanged.
1package pkg8patterns;2 3/*4 * Visitor (Behavioral)5 * --------------------6 * INTENT: represent an operation to be performed on elements of an object7 * structure; add new operations without changing the element classes.8 * UML: Element + accept(Visitor) ; Visitor + visit(ConcreteElement) per type.9 * PROS: add operations easily (double dispatch); gather related behavior.10 * CONS: adding a new element type requires editing every visitor.11 * REAL-WORLD: AST traversal/compilers, file-system operations, DOM processing.12 *13 * NOTE: Java 21 pattern matching often replaces Visitor for sealed hierarchies.14 */15public class patterns23VisitorPattern {16 17 interface Shape { <R> R accept(Visitor<R> v); }18 record Circle(double r) implements Shape { public <R> R accept(Visitor<R> v) { return v.visit(this); } }19 record Square(double s) implements Shape { public <R> R accept(Visitor<R> v) { return v.visit(this); } }20 21 interface Visitor<R> {22 R visit(Circle c);23 R visit(Square s);24 }25 26 // One operation: compute area27 static class AreaVisitor implements Visitor<Double> {28 public Double visit(Circle c) { return Math.PI * c.r() * c.r(); }29 public Double visit(Square s) { return s.s() * s.s(); }30 }31 // Another operation, added WITHOUT touching the shapes: describe32 static class DescribeVisitor implements Visitor<String> {33 public String visit(Circle c) { return "Circle r=" + c.r(); }34 public String visit(Square s) { return "Square s=" + s.s(); }35 }36 37 public static void main(String[] args) {38 Shape[] shapes = { new Circle(2), new Square(3) };39 AreaVisitor area = new AreaVisitor();40 DescribeVisitor describe = new DescribeVisitor();41 for (Shape shape : shapes) {42 System.out.printf("%s has area %.2f%n", shape.accept(describe), shape.accept(area));43 }44 }45}