C#树节点class设计
C# tree node class design
我正在寻找一些关于如何组织分层树节点的建议 class。
我有一个分层树,其中包含一些与树相关的成员,例如 Parent
、Children
、AddNode()
、RemoveNode()
等。每个节点都使用一个应用程序-具体数据也是。在阅读了大量文章后,我最终得出了两种可能的设计:
将与树相关的成员与单个树节点中的节点值成员合并class:
public class TreeNodeClass {
// tree-specific members
public TreeNodeClass Parent { get; set; }
public IList<TreeNodeClass> Children { get; set; }
public void AddNode() { }
public void RemoveNode() { }
public IEnumerable<TreeNodeClass> Traverse() { }
<...>
// value-specific members
public Type1 ValueSpecificProperty1 { get; set; }
<...>
public TypeN ValueSpecificPropertyN { get; set; }
public void Method1() { }
<...>
public void MethodN() { }
}
在单独的 classes:
中拆分树节点和节点值
1) 仅包含树相关成员的树节点class;
2) 节点值 class 仅包含特定于值的成员并通过节点对象中的 Value
成员引用此对象。
public class TreeNodeClass {
public TreeNodeClass Parent { get; set; }
public IList<TreeNodeClass> Children { get; set; }
public TreeNodeValue Value { get; set; }
public void AddNode() { }
public void RemoveNode() { }
public IEnumerable<TreeNodeClass> Traverse() { }
<...>
}
public class TreeNodeValue {
public Type1 ValueSpecificProperty1 { get; set; }
<...>
public TypeN ValueSpecificPropertyN { get; set; }
public void Method1() { }
<...>
public void MethodN() { }
}
我的具体场景的一些细节:
- 节点值class应该有大约15个轻量级属性(它们是
int
、byte
、bool
和string
类型)和5-10 种方法。
- 截至目前,节点值不应该与其树节点对话,因此不需要节点值交叉引用。但是,树节点对象将与节点值对话(通过第二个设计中的
Value
属性)。
我敢打赌这两种情况都是有效的(因为它们在很多文章中被广泛使用),所以问题是:
- 是否喜欢这些设计?
- 如果没有,那么在选择之前我应该考虑哪些因素?
我会分开关注。树的关注点是维护修改后的树不变量。每个节点中数据的关注点是,无论它关注什么。
我要做的是创建一个通用容器类型 Tree<T>
并让树对它的值一无所知,而这些值一无所知 关于他们所在的树。
现在,在某些情况下,树必须知道一些值。例如,假设您正在构建一个权重平衡的二叉树,而不是您在此处构建的 n 元树。权重平衡的二叉树必须能够查询节点以找出 "heavy" 它们如何产生可接受的平衡。有几种方法可以做到这一点。一种方法是要求 T
实现一些 IWeight
接口。另一种方法是要求树的创建者提供可以产生 T
权重的 Func<T, double>
委托。无论哪种方式,树只知道它为完成其工作所需的节点信息:维护树不变量。
我正在寻找一些关于如何组织分层树节点的建议 class。
我有一个分层树,其中包含一些与树相关的成员,例如 Parent
、Children
、AddNode()
、RemoveNode()
等。每个节点都使用一个应用程序-具体数据也是。在阅读了大量文章后,我最终得出了两种可能的设计:
将与树相关的成员与单个树节点中的节点值成员合并class:
public class TreeNodeClass {
// tree-specific members
public TreeNodeClass Parent { get; set; }
public IList<TreeNodeClass> Children { get; set; }
public void AddNode() { }
public void RemoveNode() { }
public IEnumerable<TreeNodeClass> Traverse() { }
<...>
// value-specific members
public Type1 ValueSpecificProperty1 { get; set; }
<...>
public TypeN ValueSpecificPropertyN { get; set; }
public void Method1() { }
<...>
public void MethodN() { }
}
在单独的 classes:
中拆分树节点和节点值1) 仅包含树相关成员的树节点class;
2) 节点值 class 仅包含特定于值的成员并通过节点对象中的 Value
成员引用此对象。
public class TreeNodeClass {
public TreeNodeClass Parent { get; set; }
public IList<TreeNodeClass> Children { get; set; }
public TreeNodeValue Value { get; set; }
public void AddNode() { }
public void RemoveNode() { }
public IEnumerable<TreeNodeClass> Traverse() { }
<...>
}
public class TreeNodeValue {
public Type1 ValueSpecificProperty1 { get; set; }
<...>
public TypeN ValueSpecificPropertyN { get; set; }
public void Method1() { }
<...>
public void MethodN() { }
}
我的具体场景的一些细节:
- 节点值class应该有大约15个轻量级属性(它们是
int
、byte
、bool
和string
类型)和5-10 种方法。 - 截至目前,节点值不应该与其树节点对话,因此不需要节点值交叉引用。但是,树节点对象将与节点值对话(通过第二个设计中的
Value
属性)。
我敢打赌这两种情况都是有效的(因为它们在很多文章中被广泛使用),所以问题是:
- 是否喜欢这些设计?
- 如果没有,那么在选择之前我应该考虑哪些因素?
我会分开关注。树的关注点是维护修改后的树不变量。每个节点中数据的关注点是,无论它关注什么。
我要做的是创建一个通用容器类型 Tree<T>
并让树对它的值一无所知,而这些值一无所知 关于他们所在的树。
现在,在某些情况下,树必须知道一些值。例如,假设您正在构建一个权重平衡的二叉树,而不是您在此处构建的 n 元树。权重平衡的二叉树必须能够查询节点以找出 "heavy" 它们如何产生可接受的平衡。有几种方法可以做到这一点。一种方法是要求 T
实现一些 IWeight
接口。另一种方法是要求树的创建者提供可以产生 T
权重的 Func<T, double>
委托。无论哪种方式,树只知道它为完成其工作所需的节点信息:维护树不变量。