例如,我有一个二叉树的Node
类。
public class Node {
public Node lchild;
public Node rchild; // public for convenience
}
现在,我有一个处理器,需要记录有关Node
个实例的其他信息,而只能私下使用它们。假设预订树中的数字遍历。
我认为直接的方法是在课堂上添加一个字段:
public class Node {
public Node lchild;
public Node rchild;
public int no; // the number in the pre-order tree traverse
}
但是,我认为这绝对是一个坏主意。所以我现在使用的是:使用Map<Node, Integer>
public class MyProcessor {
private Map<Node, Integer> no;
public void process1(Node node) {
int id = no.get(node); // or something like this
}
}
当然,这可以解决问题。但我担心的是:
那么,有更好的方法吗?谢谢!
答案 0 :(得分:2)
答案 1 :(得分:0)
这是一个关注点分离的问题。您想要添加的信息是节点还是树的处理器。
我会说,以下陈述描述了这种情况
所以我将信息与节点放在一起或关联起来。为了获得一定程度的灵活性,您可以获得Node
扩展名的信息class ExtNode extends Node {
int no;
}
或装饰者:
class NodeDecorator {
Node node;
int no;
NodeDecorator(node){
this.node = node;
}
}
如果您选择地图,效率不应该是您在此阶段的关注点。访问地图非常有效。如果需要,您可以稍后进行优化。
如果添加了其他信息,您可以定义一个新结构,假设NodeInfo
并将所有信息放在那里并将其放在Map或Node中而不是int。
例如
class NodeInfo {
int no;
String other;
}
答案 2 :(得分:0)
附加信息特定于Node层次结构的一个处理器,因此不应泄漏到节点中(关注点分离)
潜在的解决方案:
由于Node是树结构,因此使用在访问Node结构时构建的并行结构。这个并行项(ProcessedNode?)将保存附加信息,对Node的引用以及左/右ProcessedNode子项。
这在内存和访问方面可能更好(没有Map开销),但使处理器更复杂:它将访问ProcessedNode而不是Node。它将为下一个Node创建一个ProcessedNode,而不是访问下一个Node,并访问ProcessedNode。
您可以延迟构建ProcessedNode,因此可以根据需要构建并行树。
如果节点树可能会发生变异,并且您需要将ProcessedNode信息保留超过一次处理的持续时间,这是不切实际的。
您可以在包含附加信息的类详细信息中收集所有这些信息,而不是每个附加信息都有一个地图,并使用单个地图
该解决方案的优点是实现简单。 缺点是如果保留地图,则需要维护节点是否消失。
最终的选择取决于需要多长时间的额外细节,如果您只需要在处理期间维护信息,那么地图将在处理结束时被删除,因此添加项目的成本没有利用地图。
如果创建Map是切实可行的,那么在使用备用解决方案进行优化之前,您应该测量实际开销是多少:获得的收益是值得的吗?
答案 3 :(得分:0)
对于子分类方法,你应该使用&#34; getter方法&#34;用于访问子节点,以便子类可以覆盖它们。
public class Node {
protected Node left;
protected Node right;
public Node(Node left, Node right) {
this.left = left;
this.right = right;
}
public Node getLeft() { return left; }
public Node getRight() { return right; }
}
在子类中覆盖它们,在需要时懒洋洋地创建子节点。
public class DecoratedNode extends Node {
private Node original;
private int no = 0;
public DecoratedNode(Node n) {
super(null, null);
original = n;
}
@Override
public Node getLeft() {
if (left == null && original.getLeft() != null)
left = new DecoratedNode(original.getLeft());
return left;
}
@Override
public Node getRight() {
if (right == null && original.getRight() != null)
right = new DecoratedNode(original.getRight());
return right;
}
public int getNo() { return no; }
public void setNo(int no) { this.no = no; }
}
然后将new DecoratedNode(root)
传递给流程方法。