В настоящее время я борюсь с реализацией набора классов файловой системы. Я предполагаю, что это требует составного паттерна, если я не ошибаюсь. Поэтому я настроил следующие классы:
Абстрактный класс Node
, который имеет ссылку на свою родительскую папку и два класса Folder
и File
, которые реализуют Node
. Папка содержит коллекцию всех своих дочерних элементов и методов для добавления и удаления дочерних элементов.
Дело в том, что я не могу понять, как правильно реализовать все методы. Во всех примерах, которые я видел, нет ссылки на родителя у детей. Как метод AddChild
может гарантировать, что родительская ссылка на ребенка установлена правильно? Я решил это, проверив, был ли child.Parent
уже установлен в папку или он выдает ArgumentException
. Ситуация усложняется еще и тем, что AddChild
может также выдавать исключение, например DuplicateNameException
или что-то в этом роде. Теперь мои методы выглядят так:
File.AddTo(Folder folder) {
this.Parent = folder;
try {
folder.AddChild(this);
} catch {
this.Parent = null;
throw;
}
}
Folder.AddChild(Node child)
{
if(child.Parent != this)
throw new ArgumentException(...);
...
}
Теперь у меня есть этот уродливый AddTo
метод, и я не могу сделать что-то вроде someFolder.AddChild(new File(...))
. Интересно, как это было реализовано с ListViewItem
например. Там я могу просто сделать someListView.Items.Add(new ListViewItem(...))
.
Мое решение работает, но я не уверен, что это правильный способ сделать это. Может быть, у кого-то есть лучшее решение или может привести хороший пример. Заранее спасибо.
РЕДАКТИРОВАТЬ : минимальные полные определения классов ниже.
abstract class Node
{
public Folder Parent { get; protected set; }
public string Name { get; private set; }
public Node(string name) {
Parent = null;
Name = name;
}
}
class Folder : Node {
private Dictionary<string, Node> _children;
public Folder(string name) : base(name) {
// Other initializations here...
}
public void AddChild(Node child) {
if(child is Folder)
((Folder)child).Parent = this; // Damn, doesn't work for files!!!
else if(child.Parent != this)
throw new ArgumentException();
if(_children.ContainsKey(child.Name))
throw new DuplicateNameException();
_children[child.Name] = child;
}
}
class File : Node {
public File(string name) : base(name) {
// Other initializations here...
}
public void AddTo(Folder folder) {
Parent = folder;
try {
folder.AddChild(this);
} catch {
Parent = null;
}
}
}