这种设计模式合乎逻辑吗?

时间:2010-12-08 07:54:42

标签: c# decorator composite design-patterns

以下C#是抽象的,所以你可以看到我想要完成的结构 这是我用来表示FileSystem树的复合(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
}

我对上述代码的问题是现在我有File没有实现添加或删除...
我可以:

  1. 从组件中删除添加和删除,但后来我相信我正在打破模式。
  2. 使用补充模式(装饰器?)来更改叶和复合类中的Add。例如,force Folder以某种方式有一个方法Folder.AddFileOrFolder(Component)和File有File.AddSibling(File)。
  3. 查看其他模式。也许我做错了或者在不了解我的要求的情况下尝试完成一些不可能的事情?例如,一些问题是我使用的模式如何/应该与查看对象以及用户输入如何影响对象进行交互。
  4. 这些文件和文件夹实际上是远程主机上对象的表示,它们不是硬盘上的实际文件和文件夹。一个用户交互将是当应用程序中的“文件”被拖到桌面上时,文件被下载。

    奖金(一些相关的)问题:
    什么是一个很好的技巧或技术来缓存我的应用程序中的文件,以便如果用户确实与“虚拟”文件交互,他们会更快地看到结果。

    谢谢。

4 个答案:

答案 0 :(得分:2)

我建议只有两个类,文件夹和文件。文件夹有两个集合,文件夹和文件。不需要用不合适的模式使其复杂化。如果“文件和文件夹”具有一些常用方法/属性(例如“名称”),则可以仅为共享方法/属性创建适当的接口。

答案 1 :(得分:1)

我同意@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;}
}

不要在没有理由的情况下尝试使用模式,只会使事情复杂化。

答案 2 :(得分:1)

如果您计划使用复合模式实现访问者模式,则此处使用复合模式特别有用。换句话说,随着时间的推移,您可能希望在文件/文件夹结构上添加任意数量的无法预料的活动。例如,您不知道您需要能够检查文件系统中包含对EnvDTE的引用的csproj文件或计算零长度文件的数量。通过这两种模式的组合,这很容易。有时模式很有用。有时他们会在历史中写下“看起来有人在学习模式”。通过工程贸易研究考虑更大的业务需求。特别要确定是否需要可扩展性或可扩展性并做出决定。

答案 3 :(得分:0)

我认为几乎所有使用接口的模式都存在同样的问题。接口方法的调用者无法保证实现者执行特定任务,或者确实做任何事情。这让我感到不满,而且我不确定我是否对这个哲学问题感到满意。

我的一个想法是期望每个接口方法都返回一个类的实例 - 这个类应该有一个私有构造函数,并且需要某些步骤来创建它,以“证明”创建方法正在做一些相关的事情。这就像工作的“报告”一样,一个陌生人 - 一个接口实现者 - 可以返回给调用者进行验证。

另一方面,这可以被认为是一种反模式,因为接口的关键是你关心底层实现。这意味着你必须构造你的代码,如果它没有暴露预期的行为,而不是调用者的行为,那么它就是实现者的问题。