Annotation Type GenerateVisitor
Annotation to cause the annotation processor
GenerateVisitorAnnotationProcessor
to create a visitor for all
implementors of an interface or all subclasses of a root class that can be discovered in the current compilation unit.
The generated visitor interface contains an overloaded visit method per discovered implementor/subclass and a
polymorphic method T visit(element)
that dispatches to the right visitation method for the element that
is passed in.
The interface that is generated should be implemented by all visitors visiting the class hierarchy.
Motivation: The visitor design pattern can be immensely useful if used wisely. In essence, the visitor
design pattern allows for multiple dispatch over two (and if needed) more subjects by chaining single dynamic
dispatch on selfish methods. Furthermore, it allows the user to write code that is specific to subclasses of a
hierarchy inside the visitor rather than scattering that same code over many subclasses/implementors in the form
of overrides.
Using the visitor design pattern in Java may cause some boilerplate which in turn may turn out to be error-prone
and not maintainable:
- A code maintenance problem usually arises over time when the visitor pattern is employed as class hierarchies are modified, new implementors are added, so it would be useful to get a compiler error if a visitor has not implemented a visitation method (yet).
- The accept method of the visitor has to be written in the form of overrides inside the original class hierarchy. Again, it's tedious to do that (and maintain it) for the visitor/class pair.
SomeRootClass
,
an interface called SomeRootClassVisitor<T>
is generated which defines a method
T visitSpecificClass(SpecificClass element);
for each subclass/implementor and returns some generic type T
. This generated interface needs to be
implemented by the user. If the hierarchy of classes is changed in some way, the visitor interface (which would be
regenerated by the build process) potentially causes compilation errors if implementations of the visitor interface
have not (yet) been adapted to that change.
In addition to the specific visitation methods there is a method
T visit(SomeRootClass element);
which when called on an element
dispatches to the right override based on the dynamic type of element
.
That eliminates the need for writing accept methods.-
Optional Element Summary
Optional ElementsModifier and TypeOptional ElementDescription...
-
Element Details
-
classSuffix
String classSuffix.- Returns:
- suffix of the generated visitor interface
- Default:
- "Visitor"
-
methodPrefix
String methodPrefix.- Returns:
- prefix of all visitation methods
- Default:
- "visit"
-
stripPrefix
String stripPrefix.- Returns:
- prefix we should attempt to remove from every discovered subclass when creating the name for the specific visitation method
- Default:
- ""
-