I would like to have on different types of nodes (Node
) in the tree called code different actions (Action
). I tried to write code so that adding new actions to the nodes of the tree has implemented the most simple.
I have a tree whose nodes are of type Node
:
import java.util.List; public interface Node { String value(); List<Node> childs(); }
I have two implementations of Node
:
public final class NodeType1 implements Node { private final String value; private final List<Node> childs; public NodeType1(String value, List<Node> childs) { this.value = value; this.childs = childs; } @Override public String value() { return this.value; } @Override public List<Node> childs() { return this.childs; } } public final class NodeType2 implements Node { private final String value; private final List<Node> childs; public NodeType2(String value, List<Node> childs) { this.value = value; this.childs = childs; } @Override public String value() { return this.value; } @Override public List<Node> childs() { return this.childs; } }
I have Action
interface and two implementation:
public interface Action { void act(Node node); } public final class Action1 implements Action { @Override public void act(final Node node) { System.out.println("Act action1 (" + node.value() + ")"); } } public final class Action2 implements Action { @Override public void act(final Node node) { System.out.println("Act action2 (" + node.value() + ")"); } }
I also created ActionSet
class for group actions
import java.util.LinkedList; import java.util.List; public class ActionSet { private List<Action> actions = new LinkedList<>(); public ActionSet(final List<Action> actions) { this.actions = actions; } public boolean add(final Action action) { return actions.add(action); } public void act(final Node node) { for (final Action action : this.actions) { action.act(node); } } }
This is ActionSet1
and ActionSet2
:
public final class ActionSet1 extends ActionSet { public ActionSet1() { super(new LinkedList<Action>() {{ add(new Action1()); }}); } } public final class ActionSet2 extends ActionSet { public ActionSet2() { super(new LinkedList<Action>() {{ add(new Action2()); }}); } }
And I created TreeWalker
class:
public final class TreeWalker { public void walk(final Node root) { if (root instanceof NodeType1) { walk((NodeType1) root); } else if (root instanceof NodeType2) { walk((NodeType2) root); } } public void walk(final NodeType1 root) { new ActionSet1().act(root); for (final Node child : root.childs()) { walk(child); } } public void walk(final NodeType2 root) { new ActionSet2().act(root); for (final Node child : root.childs()) { walk(child); } } }
Finally this is my main Application
class:
import java.util.LinkedList; public final class Application { public static void main(final String[] args) { final Node tree = new NodeType2("hello", new LinkedList<Node>() {{ add(new NodeType1("world", new LinkedList<Node>())); add(new NodeType2("bold", new LinkedList<Node>())); }}); final TreeWalker walker = new TreeWalker(); walker.walk(tree); } }
If you execute this application you can see:
Act action2 (hello) Act action1 (world) Act action2 (bold)
How do you evaluate this design? What problems can it cause and what can be improved?