У меня есть объект Category (класс), у которого есть ноль или одна родительская категория и много дочерних категорий - это древовидная структура. Данные категории хранятся в СУБД, поэтому для повышения производительности я хочу загрузить все категории и кэшировать их в памяти при запуске приложения.
В нашей системе могут быть подключаемые модули, и мы разрешаем авторам подключаемых модулей получать доступ к Дереву категорий, но они не должны изменять кэшированные элементы и дерево (я думаю, что дизайн, не предназначенный только для чтения, может вызвать некоторые незначительные ошибки в этом senario) только система знает, когда и как обновить дерево.
Вот несколько демонстрационных кодов:
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 доступным для записи, то мы не сможем сделать дерево категорий доступным только для чтения , это нехорошо.
Так что я думаю, что если мы сможем сделать так:
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; }
}
Это хорошо или плохо? Есть ли лучшие дизайны? Большое спасибо! :)