Skip to content

Instantly share code, notes, and snippets.

@szarnekow
Last active December 15, 2015 06:09
Show Gist options
  • Save szarnekow/5213798 to your computer and use it in GitHub Desktop.
Save szarnekow/5213798 to your computer and use it in GitHub Desktop.
Illustration of the visitor pattern with Active Annotations.
@Visitable
abstract class CarElement {
// placeholder
def void accept(CarElementVisitor visitor)
}
@Data
class Wheel extends CarElement {
String name;
}
class Engine extends CarElement {}
class Body extends CarElement {}
class Car extends CarElement {
CarElement[] elements;
new() {
this.elements = #[
new Wheel("front left"),
new Wheel("front right"),
new Wheel("back left"),
new Wheel("back right"),
new Body(),
new Engine()
]
}
override void accept(CarElementVisitor visitor) {
elements.forEach[ accept(visitor) ]
visitor.visitCar(this)
}
}
public abstract class CarElement {
public void acceptPrintVisitor(final PrintingVisitor visitor, final StringBuilder result) {
visitor.visitCarElement(this, result);
}
public int acceptCountingVisitor(final CountingVisitor visitor) {
return visitor.visitCarElement(this);
}
}
public class PrintingVisitor {
public void visitCarElement(final CarElement visitable, final StringBuilder result) {
throw new IllegalStateException();
}
public void visitWheel(final Wheel visitable, final StringBuilder result) {
visitCarElement(visitable, result);
}
public void visitEngine(final Engine visitable, final StringBuilder result) {
visitCarElement(visitable, result);
}
public void visitBody(final Body visitable, final StringBuilder result) {
visitCarElement(visitable, result);
}
public void visitCar(final Car visitable, final StringBuilder result) {
visitCarElement(visitable, result);
}
}
public class CountingVisitor {
public int visitCarElement(final CarElement visitable) {
throw new IllegalStateException();
}
public int visitWheel(final Wheel visitable) {
return visitCarElement(visitable);
}
public int visitEngine(final Engine visitable) {
return visitCarElement(visitable);
}
public int visitBody(final Body visitable) {
return visitCarElement(visitable);
}
public int visitCar(final Car visitable) {
return visitCarElement(visitable);
}
}
@Visitable
abstract class CarElement {
def void acceptPrintVisitor(PrintingVisitor visitor, StringBuilder result)
def int acceptCountingVisitor(CountingVisitor visitor)
}
class CarElementPrintVisitor extends CarElementVisitor {
override void visitWheel(Wheel wheel) {
println("Visiting " + wheel.getName() + " wheel");
}
override void visitEngine(Engine engine) {
println("Visiting engine");
}
override void visitBody(Body body) {
println("Visiting body");
}
override void visitCar(Car car) {
println("Visiting car");
}
}
class CarElementDoVisitor extends CarElementVisitor {
override void visitWheel(Wheel wheel) {
println("Kicking my " + wheel.getName() + " wheel");
}
override void visitEngine(Engine engine) {
println("Starting my engine");
}
override void visitBody(Body body) {
println("Moving my body");
}
override void visitCar(Car car) {
println("Starting my car");
}
}
@szarnekow
Copy link
Author

Here you can find the implementation of @Visitable: https://gist.github.com/szarnekow/5214080

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment