Логичен ли этот шаблон проектирования? - PullRequest
0 голосов
/ 08 декабря 2010

Следующий C # является абстрактным, поэтому вы можете увидеть структуру того, что я пытаюсь выполнить
Это составной (GoF) шаблон, который я использую для представления дерева файловой системы

interface IComponent
{
    void Render();
    void Add(INode);
    void Remove(INode);
}

class Folder : IComponent
{
    List<IComponent> filesAndFolders = new List<IComponent>();

    void Render()
    {
        Console.WriteLine("This is a folder, num childs: " + 
    }

    void Add(IComponent add)
    {
        filesAndFolders.Add(add);
    }

    void Remove(IComponent rem)
    {
        filesAndFolders.Remove(rem);
    }
}

class File : IComponent
{
    void Render()
    {
        Console.WriteLine("This is a file");
    }

    void Add(IComponent add)
    {
    //do nothing... cant add folder to file
    }

    void Remove() { } //same as above
}

Моя проблема с приведенным выше кодом теперь у меня есть Файл, который не реализует Добавить или Удалить ...
Я мог бы:

  1. Удалите добавление и удалите из Компонента , но тогда я считаю, что немного нарушаю шаблон.
  2. Используйте шаблон дополнения (декоратор?) Для изменения Add в листовых и составных классах. Например, заставить Folder каким-либо образом иметь метод Folder.AddFileOrFolder (Component) и File, чтобы иметь File.AddSibling (File).
  3. Посмотрите на другой шаблон . Возможно, я делаю это неправильно или пытаюсь сделать что-то невозможное, не зная больше о моих требованиях? Например, некоторые вопросы могут быть о том, как / должен ли шаблон, который я использую, взаимодействовать с просмотром объектов и как пользовательский ввод влияет на объекты.

Эти файлы и папки действительно представляют собой объекты на удаленном хосте, они не являются действительными файлами и папками на жестком диске. Одно взаимодействие с пользователем будет происходить, когда «файл» в приложении перетаскивается на рабочий стол, файл загружается.

Бонус (кое-что связанное) вопрос:
Что было бы хорошим приемом или техникой для кэширования файлов в моем приложении, чтобы, если пользователь действительно взаимодействует с «виртуальным» файлом, он видел результат быстрее.

Спасибо.

Ответы [ 4 ]

2 голосов
/ 08 декабря 2010

Я бы предложил просто иметь два класса, Папка и Файл.Папка имеет две коллекции, папки и файлы.Не нужно усложнять это плохо приспособленными узорами.Если у файлов и папок есть некоторые общие методы / свойства (например, Имя), вы можете создать соответствующий интерфейс только для общих методов / свойств.

1 голос
/ 31 мая 2012

Использование составного шаблона здесь особенно полезно, если вы планируете реализовать с ним шаблон посетителя. Другими словами, со временем вы можете захотеть добавить любое количество непредвиденных действий в структуру вашего файла / папки. Например, вы не знали, что вам нужна возможность проверять вашу файловую систему на наличие файлов csproj, содержащих ссылку на EnvDTE, или подсчитывать количество файлов нулевой длины. Это легко с комбинацией этих двух моделей. Иногда шаблоны полезны. Иногда они уходят в историю как «похоже, что кто-то изучал шаблон». Рассмотрите более крупные бизнес-требования с изучением инженерной профессии. Определите, есть ли необходимость в масштабируемости или расширяемости, и примите решение.

1 голос
/ 08 декабря 2010

Я согласен с @Brian. Я бы создал интерфейс с информацией, которая существует как для файлов, так и для папок.

interface IFileSystemItem
{
    string Name {get; set;}

    // folder for files, parent folder for folders, null for root folders.
    IFileSystemItem Parent {get;set;}

    DateTime CreatedAt {get;set;}

    DateTime ModifiedAt {get;set;}

    ISecurityInfo SecurityInfo {get;set;}
}

Не пытайтесь использовать шаблоны без причины, это только усложнит ситуацию.

0 голосов
/ 08 декабря 2010

Я чувствую ту же проблему почти со всеми шаблонами, которые используют интерфейсы. Вызывающий метод интерфейса не имеет никакой гарантии , что разработчик выполняет определенную задачу или действительно вообще что-либо делает. Это меня не устраивает, и я не уверен, что знаю приятное решение этой философской проблемы.

У меня была одна идея - ожидать, что каждый интерфейсный метод будет возвращать экземпляр класса - этот класс должен иметь закрытый конструктор и требовать определенных шагов для его создания, чтобы «доказать», что метод создания делает что-то важное. Это было бы похоже на «отчет» о проделанной работе, что незнакомец, которым является реализатор интерфейса, может вернуться к вызывающей стороне для проверки.

С другой стороны, это можно считать анти-паттерном, потому что смысл интерфейсов в том, что вы не заботитесь о базовой реализации. Это означает, что вы должны структурировать свой код, так что это проблема разработчика, если он не раскрывает ожидаемое поведение, а не вызывающего.

...