元ネタ:Visitorパターンについて考えた — 裏紙
Xtend なら dispatch という構文 が追加されているので Groovy 位簡単に書けます。
interface Node{} @Data class NumNode implements Node { int value } @Data class AddNode implements Node { Node right Node left } class Calculator { def dispatch int visit(NumNode node) { node.value } def dispatch int visit(AddNode node) { visit(node.left) + visit(node.right) } def static void main(String... args) { val node1 = new NumNode(2) val node2 = new NumNode(3) val node3 = new AddNode(node1, node2) val node4 = new NumNode(4) val node5 = new AddNode(node3, node4) val calculator = new Calculator() val actual = calculator.visit(node5) println(actual) // 9 } }
生成される .java はこんなのです
import java.util.Arrays; import org.eclipse.xtext.xbase.lib.InputOutput; @SuppressWarnings("all") public class Calculator { protected int _visit(final NumNode node) { int _value = node.getValue(); return _value; } protected int _visit(final AddNode node) { Node _left = node.getLeft(); int _visit = this.visit(_left); Node _right = node.getRight(); int _visit_1 = this.visit(_right); int _plus = (_visit + _visit_1); return _plus; } public int visit(final Node node) { if (node instanceof AddNode) { return _visit((AddNode)node); } else if (node instanceof NumNode) { return _visit((NumNode)node); } else { throw new IllegalArgumentException("Unhandled parameter types: " + Arrays.<Object>asList(node).toString()); } } public static void main(final String... args) { NumNode _numNode = new NumNode(2); final NumNode node1 = _numNode; NumNode _numNode_1 = new NumNode(3); final NumNode node2 = _numNode_1; AddNode _addNode = new AddNode(node1, node2); final AddNode node3 = _addNode; NumNode _numNode_2 = new NumNode(4); final NumNode node4 = _numNode_2; AddNode _addNode_1 = new AddNode(node3, node4); final AddNode node5 = _addNode_1; Calculator _calculator = new Calculator(); final Calculator calculator = _calculator; final int actual = calculator.visit(node5); InputOutput.<Integer>println(Integer.valueOf(actual)); } }
dispatch 付のメソッドは、"_" 付でそれぞれのメソッドが生成され、元の名前では、引数の共通の型で受け instanceOf したコードが生成されます。
パラメータの数が複数でも大丈夫です。
Xtend - Modernized Java Dispatch Methods