Last active
December 16, 2015 22:29
-
-
Save haiiro-shimeji/5507517 to your computer and use it in GitHub Desktop.
子どもとして持てるノードタイプを型として定義可能なツリー構造が作りたかった
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
| import java.util.ArrayList; | |
| import java.util.Arrays; | |
| import java.util.List; | |
| import org.junit.Test; | |
| /** | |
| * 子どもとして持てるノードタイプを型として定義可能なツリー構造が作りたかった | |
| */ | |
| public class Test1 { | |
| private static class Tree { | |
| static class Node { | |
| List<Node> children = new ArrayList<Node>(); | |
| } | |
| static class RestrictedNode<T extends Node> extends Node { | |
| RestrictedNode<T> append(T node, T... more) { | |
| children.add(node); | |
| children.addAll(Arrays.asList(more)); | |
| return this; | |
| } | |
| } | |
| static class FreeNode extends RestrictedNode<Node> {} | |
| static public class NodeType1 extends FreeNode {} | |
| //NodeType2 can include NodeType3 | |
| static public class NodeType2 extends RestrictedNode<NodeType3> {} | |
| static public class NodeType3 extends FreeNode {} | |
| } | |
| Tree.NodeType1 nodeType1() { | |
| return new Tree.NodeType1(); | |
| } | |
| Tree.NodeType2 nodeType2() { | |
| return new Tree.NodeType2(); | |
| } | |
| Tree.NodeType3 nodeType3() { | |
| return new Tree.NodeType3(); | |
| } | |
| @Test | |
| public void test() { | |
| nodeType1().append( | |
| nodeType1().append( | |
| nodeType2(), | |
| nodeType3().append( | |
| nodeType1() | |
| ) | |
| ), | |
| nodeType2().append( | |
| //nodeType1(), //compilation error. | |
| //nodeType2(), //compilation error. | |
| nodeType3() | |
| ), | |
| nodeType3() | |
| ); | |
| } | |
| } |
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
| import java.util.ArrayList; | |
| import java.util.HashMap; | |
| import java.util.List; | |
| import java.util.Map; | |
| import org.junit.Test; | |
| /** | |
| * ノードの生成にBuilderが使いたくなったがだめだった | |
| */ | |
| public class Test2 { | |
| static class Tree { | |
| private static class Node { | |
| List<Node> children = new ArrayList<Node>(); | |
| Map<String, String> attributes = new HashMap<String, String>(); | |
| } | |
| static class RestrictedNode<T extends Node> extends Node { | |
| RestrictedNode<T> append(NodeBuilder<T> builder, NodeBuilder<T>... more) { | |
| children.add(builder.build()); | |
| for (NodeBuilder<T> b: more) { | |
| children.add(b.build()); | |
| } | |
| return this; | |
| } | |
| } | |
| static class FreeNode extends RestrictedNode<Node> {} | |
| static public class NodeType1 extends FreeNode {} | |
| //NodeType2 can include NodeType3 | |
| static public class NodeType2 extends RestrictedNode<NodeType3> {} | |
| static public class NodeType3 extends FreeNode {} | |
| static public class NodeBuilder<T extends Node> { | |
| final T node; | |
| public NodeBuilder(T node) { | |
| this.node = node; | |
| } | |
| public NodeBuilder<T> attr(String name, String value) { | |
| node.attributes.put(name, value); | |
| return this; | |
| } | |
| public NodeBuilder<T> append(NodeBuilder<? extends Node> builder, NodeBuilder<? extends Node>... more) { | |
| node.append(builder, more); //アカン | |
| return this; | |
| } | |
| T build() { | |
| return node; | |
| } | |
| } | |
| } | |
| Tree.NodeBuilder<Tree.NodeType1> nodeType1() { | |
| return new Tree.NodeBuilder(new Tree.NodeType1()); | |
| } | |
| Tree.NodeBuilder<Tree.NodeType2> nodeType2() { | |
| return new Tree.NodeBuilder(new Tree.NodeType2()); | |
| } | |
| Tree.NodeBuilder<Tree.NodeType3> nodeType3() { | |
| return new Tree.NodeBuilder(new Tree.NodeType3()); | |
| } | |
| @Test | |
| public void test() { | |
| nodeType1() | |
| .attr("hoge", "fuga") | |
| .append( | |
| nodeType1() | |
| .attr("hoge", "fuga") | |
| .append( | |
| nodeType2(), | |
| nodeType3().append( | |
| nodeType1() | |
| ) | |
| ), | |
| nodeType2().append( | |
| nodeType1(), //コンパイルエラーにならない | |
| nodeType2(), //コンパイルエラーにならない | |
| nodeType3() | |
| ), | |
| nodeType3() | |
| ); | |
| } | |
| } |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment