Hi all,
I have a Category entity (class), which has zero or one parent Category and many child Categories -- it's a tree structure. The Category data is stored in a RDBMS, so for better performance, I want to load all categories and cache them in memory while launching the applicaiton.
Our system can have plugins, and we allow the plugin authors to access the Category Tree, but they should not modify the cached items and the tree(I think a non-readonly design might cause some subtle bugs in this senario), only the system knows when and how to refresh the tree.
Here are some demo codes:
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
}
}
So far so good. However, I want to make ITreeNode interface reuseable, and for some other types, the tree should not be readonly. We are not able to do this with the above readonly ITreeNode, so I want the ITreeNode to be like this:
public interface ITreeNode<T> {
// has setter
T Parent { get; set; }
// use ICollection<T> instead of IEnumerable<T>
ICollection<T> ChildNodes { get; }
}
But if we make the ITreeNode writable, then we cannot make the Category Tree readonly, it's not good.
So I think if we can do like this:
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; }
}
Is this good or bad? Are there some better designs? Thanks a lot! :)