Created
May 25, 2019 18:38
-
-
Save norswap/7f3d40adb85491d440bdf026b738890a to your computer and use it in GitHub Desktop.
Visitors in Java 8
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
public final class Visitors | |
{ | |
// --------------------------------------------------------------------------------------------- | |
// 1. Initial setup. | |
interface Visitor { | |
void visit (A object); | |
void visit (B object); | |
} | |
interface Base { | |
void accept (Visitor visitor); | |
} | |
static class A implements Base { | |
@Override public void accept (Visitor visitor) { | |
visitor.visit(this); // calls visit(A) | |
} | |
} | |
static class B implements Base { | |
@Override public void accept (Visitor visitor) { | |
visitor.visit(this); // calls visit(B) | |
} | |
} | |
// --------------------------------------------------------------------------------------------- | |
// 2. Adding a visitor. | |
interface _PrintVisitor extends Visitor | |
{ | |
@Override default void visit (A object) { | |
System.out.println("printing an A"); | |
} | |
@Override default void visit (B object) { | |
System.out.println("printing a B"); | |
} | |
} | |
static class PrintVisitor implements _PrintVisitor {} | |
// --------------------------------------------------------------------------------------------- | |
// 3. Adding two *independent* data types C and D. | |
interface VisitorC extends Visitor { | |
void visit (C object); | |
} | |
static class C implements Base { | |
@Override public void accept (Visitor visitor) { | |
((VisitorC) visitor).visit(this); | |
} | |
} | |
interface _PrintVisitorC extends _PrintVisitor, VisitorC { | |
@Override default void visit (C object) { | |
System.out.println("printing a C"); | |
} | |
} | |
static class PrintVisitorC implements _PrintVisitorC {} | |
interface VisitorD extends Visitor { | |
void visit (D object); | |
} | |
static class D implements Base { | |
@Override public void accept (Visitor visitor) { | |
((VisitorD) visitor).visit(this); | |
} | |
} | |
interface _PrintVisitorD extends _PrintVisitor, VisitorD { | |
@Override default void visit (D object) { | |
System.out.println("printing a D"); | |
} | |
} | |
static class PrintVisitorD implements _PrintVisitorD {} | |
// --------------------------------------------------------------------------------------------- | |
// 4. Composing independent data types C & D. | |
interface _PrintVisitorCD extends _PrintVisitorC, _PrintVisitorD {} | |
static class PrintVisitorCD implements _PrintVisitorCD {} | |
// --------------------------------------------------------------------------------------------- | |
// 5. Adding a new visitor that manipulate states. | |
// Still assumes C & D where developed independently. | |
// 5.1. Initial | |
interface _AddRankVisitor extends Visitor | |
{ | |
int base(); | |
int result(); | |
void set_result (int result); | |
@Override default void visit (A object) { set_result(base() + 1); } | |
@Override default void visit (B object) { set_result(base() + 2); } | |
} | |
static class AddRankVisitor implements _AddRankVisitor | |
{ | |
private final int base; | |
private int result; | |
AddRankVisitor (int base) { this.base = base; } | |
@Override public int base () { return base; } | |
@Override public int result () { return result; } | |
@Override public void set_result (int result) { this.result = result; } | |
} | |
// 5.2. C & D extensions | |
interface _Add_RankVisitorC extends _AddRankVisitor, VisitorC { | |
@Override default void visit (C object) { set_result(base() + 3); } | |
} | |
static class AddRankVisitorC extends AddRankVisitor implements _Add_RankVisitorC { | |
AddRankVisitorC (int base) { super(base); } | |
} | |
interface _Add_RankVisitorD extends _AddRankVisitor, VisitorD { | |
@Override default void visit (D object) { set_result(base() + 4); } | |
} | |
static class AddRankVisitorD extends AddRankVisitor implements _Add_RankVisitorD { | |
AddRankVisitorD (int base) { super(base); } | |
} | |
// 5.3 Composing C & D | |
interface _Add_RankVisitorCD extends _Add_RankVisitorC, _Add_RankVisitorD {} | |
static class AddRankVisitorCD extends AddRankVisitor implements _Add_RankVisitorCD { | |
AddRankVisitorCD (int base) { super(base); } | |
} | |
// --------------------------------------------------------------------------------------------- | |
/** | |
* Example: using the rank visitor that handles A, B, C and D. | |
*/ | |
public static int add_rank (int base, Base v) | |
{ | |
AddRankVisitor visitor = new AddRankVisitorCD(base); | |
v.accept(visitor); | |
return visitor.result(); | |
} | |
// --------------------------------------------------------------------------------------------- | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment