【发布时间】:2011-12-06 14:27:23
【问题描述】:
我想通过一些额外的数据来扩展现有的双链树实现。
因此,我可以重构基本的 TreeNode 实现,但我想要一个单独的扩展 TreeNode 实现,因为在我的实际场景中,构建 ExtandedTreeNode 将比构建基本的要昂贵得多TreeNode,额外数据仅在某些用例中是必需的。
基本代码
这是我在 Java 中实现可扩展双链树的第一个基本方法:
基本树节点界面:
interface TreeNode
{
// tree node getters:
TreeNode getParent();
List<? extends TreeNode> getChildren();
// tree node setters:
void setParent(TreeNode parentNode);
void addChild(TreeNode childNode);
// some basic operations:
boolean isSelectable();
// [...]
}
扩展树节点接口:
interface ExtandedTreeNode extends TreeNode
{
// narrow types of tree node getters of super-interface:
@Override
ExtandedTreeNode getParent();
@Override
List<? extends ExtandedTreeNode> getChildren();
// narrowing types of tree node setters of super-interface is not possible!
// some additional operations:
boolean isRemoveable();
// [...]
}
基本树节点实现:
class TreeNodeImpl implements TreeNode
{
private TreeNode parent;
private List<TreeNode> children = new ArrayList<TreeNode>();
private boolean isSelectable;
//
// implement tree node getters:
//
@Override
public TreeNode getParent()
{
return parent;
}
@Override
public List<? extends TreeNode> getChildren()
{
return children;
}
//
// implement tree node setters:
//
@Override
public void setParent(TreeNode parent)
{
this.parent = parent;
}
@Override
public void addChild(TreeNode childNode)
{
children.add(childNode);
}
//
// implement basic operations:
//
@Override
public boolean isSelectable()
{
return isSelectable;
}
// [...]
}
扩展树节点实现:
class ExtandedTreeNodeImpl implements ExtandedTreeNode
{
private ExtandedTreeNode parent;
private List<ExtandedTreeNode> children = new ArrayList<ExtandedTreeNode>();
private TreeNode treeNode;
private boolean isRemoveable;
public ExtandedTreeNodeImpl()
{
treeNode = new TreeNodeImpl();
}
//
// implement tree node getters:
//
@Override
public ExtandedTreeNode getParent()
{
return parent;
}
@Override
public List<? extends ExtandedTreeNode> getChildren()
{
return children;
}
//
// implement tree node setters:
//
@Override
public void setParent(TreeNode parent)
{
this.parent = (ExtandedTreeNode) parent; // <--- How to avoid this type cast!!
}
@Override
public void addChild(TreeNode childNode)
{
children.add((ExtandedTreeNode) childNode); // <--- How to avoid this type cast!!
}
//
// implement basic operations by delegating to composite TreeNode:
//
public boolean isSelectable()
{
return treeNode.isSelectable();
}
// [...]
//
// implement additional operations:
//
@Override
public boolean isRemoveable()
{
return isRemoveable;
}
// [...]
}
问题
对我来说,类型层次结构对于只读和非树节点特定的方法看起来很棒,但它对于 setter setParent(..) 和 addChild(..) 会泄漏。特别是ExtandedTreeNode 的风险类型转换非常邪恶,我想摆脱它。
我想过将setParent(..) 和addChild(..) 方法提取到另外两个独立的接口,例如TreeNodeWriteable 和ExtandedTreeNodeWriteable,但也许有一些更好的设计解决方案。
有人知道可以解决我的可写树节点特定设置器问题的设计模式或蓝图吗?
【问题讨论】: