【发布时间】:2010-05-12 04:11:20
【问题描述】:
我有一个类别实体(类),它有零个或一个父类别和许多子类别——它是一个树结构。类别数据存储在 RDBMS 中,因此为了获得更好的性能,我想在启动应用程序时加载所有类别并将它们缓存在内存中。
我们的系统可以有插件,我们允许插件作者访问分类树,但他们不应该修改缓存的项目和树(我认为非只读设计可能会在这个场景中导致一些细微的错误),只有系统知道何时以及如何刷新树。
这里有一些演示代码:
public interface ITreeNode<T>
where T : ITreeNode<T>
{
// No setter
T Parent { get; }
IEnumerable<T> ChildNodes { get; }
}
// This class is generated by O/R Mapping tool (e.g. Entity Framework)
public class Category : EntityObject
{
public string Name { get; set; }
}
// Because Category is not stateless, so I create a cleaner view class for Category.
// And this class is the Node Type of the Category Tree
public class CategoryView : ITreeNode<CategoryView>
{
public string Name { get; private set; }
#region ITreeNode Memebers
public CategoryView Parent { get; private set; }
private List<CategoryView> _childNodes;
public IEnumerable<CategoryView> ChildNodes {
return _childNodes;
}
#endregion
public static CategoryView CreateFrom(Category category) {
// here I can set the CategoryView.Name property
}
}
到目前为止一切顺利。 但是,我想让 ITreeNode 接口可重用,并且对于其他一些类型,树不应该是只读的。我们无法用上面的只读 ITreeNode 做到这一点,所以我希望 ITreeNode 是这样的:
public interface ITreeNode<T> {
// has setter
T Parent { get; set; }
// use ICollection<T> instead of IEnumerable<T>
ICollection<T> ChildNodes { get; }
}
但是如果我们让 ITreeNode 可写,那么我们就不能让 Category Tree 只读,那就不好了。
所以我想如果我们可以这样做:
public interface ITreeNode<T> {
T Parent { get; }
IEnumerable<T> ChildNodes { get; }
}
public interface IWritableTreeNode<T> : ITreeNode<T> {
new T Parent { get; set; }
new ICollection<T> ChildNodes { get; }
}
这是好事还是坏事?有没有更好的设计?非常感谢! :)
【问题讨论】:
标签: c# .net design-patterns tree readonly