Java 什么';添加有关现有对象的附加信息的更好方法是什么?
例如,我有一个用于二叉树的Java 什么';添加有关现有对象的附加信息的更好方法是什么?,java,Java,例如,我有一个用于二叉树的节点类 public class Node { public Node lchild; public Node rchild; // public for convenience } 现在,我有一个处理器,它需要记录有关节点实例的一些附加信息,并且只能私下使用它们。让我们假设预排序树遍历中的数字 我认为一个直接的方法是在类中添加一个字段: public class Node { public Node lchild; public No
节点
类
public class Node {
public Node lchild;
public Node rchild; // public for convenience
}
现在,我有一个处理器,它需要记录有关节点
实例的一些附加信息,并且只能私下使用它们。让我们假设预排序树遍历中的数字
我认为一个直接的方法是在类中添加一个字段:
public class Node {
public Node lchild;
public Node rchild;
public int no; // the number in the pre-order tree traverse
}
不过,我相信这绝对是个坏主意。所以我现在使用的是:使用Map
公共类MyProcessor{
私人地图编号;
公共无效进程1(节点){
int id=no.get(node);//或类似的内容
}
}
当然,这可以解决问题。但我担心的是:
那么,有没有更好的办法?谢谢 最好的解决方案可能是扩展您拥有的
节点
对象,这将允许您在不破坏现有代码的同时利用新功能
您还可以将其与和模式结合起来,尝试创建一个透明、结构化的对象创建过程。这是一个关注点分离的问题。是要添加树的节点或处理器关注点的信息 我想说,下面的陈述描述了这种情况
- 树具有节点(合成聚合)
- 该节点具有多个节点(聚合)
- 该节点具有节点信息(聚合)
- 处理器处理树(依赖项)
class ExtNode extends Node {
int no;
}
或装饰师:
class NodeDecorator {
Node node;
int no;
NodeDecorator(node){
this.node = node;
}
}
如果你选择地图,在这个阶段,效率不应该是你关心的问题。访问地图是相当有效的。如果需要,您可以稍后进行优化
如果添加了其他信息,您可以定义一个新的结构,比如说NodeInfo
,将所有信息放在其中,并将其放在映射中或节点上,而不是int
比如说
class NodeInfo {
int no;
String other;
}
附加信息特定于节点层次结构的一个处理器,因此不应泄漏到节点中(关注点分离) 可能的解决办法:
如果创建一个映射是可行的,那么在使用替代解决方案进行优化之前,您应该测量实际开销:该收益值得付出努力吗?对于子分类方法,您应该使用“getter方法”访问子节点,以便子类可以覆盖它们
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; }
}
然后将新的DecoratedNode(root)传递给进程方法。“但是,我认为这绝对是个坏主意。”为什么?
Node
是否在其他处理器中重复使用?@T.J.Crowder是的,Node
被广泛共享。我想你可以将Node
子类化,并添加你想要的任意多的信息。@devuth是的,这是一个解决方案。但是我似乎需要复制节点
实例已经拥有的所有信息。您觉得使用第二种解决方案会影响性能吗?我想不会。否则,您可能会将其子类化为ProcesserNode,但如果在整个应用程序中共享相同的引用,则需要大量装箱和拆箱(性能较差)。
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; }
}