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

发布于 2024-10-06 06:31:07 字数 1299 浏览 0 评论 0原文

以下 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. 看看不同的模式。也许我做错了,或者在不了解我的要求的情况下试图完成一些不可能的事情?例如,一些问题是我使用的模式如何/应该如何与对象的查看交互以及用户输入如何影响对象。

这些文件和文件夹实际上是远程主机上对象的表示,而不是硬盘上实际的文件和文件夹。一种用户交互是当应用程序中的“文件”被拖到桌面上时,文件被下载。

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

谢谢。

The following C# is abstract so you can see the structure of what I am trying to accomplish
This is the Composite (GoF) Pattern I am using to represent a FileSystem tree

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
}

My problem with the above code is now I have File which does not implement Add or Remove...
I could:

  1. Remove the add and remove from Component, but then I believe I am breaking the pattern a bit.
  2. Use a complement pattern (decorator?) to change Add in the leaf and composite classes. For example, force Folder somehow to have a method Folder.AddFileOrFolder(Component) and File to have File.AddSibling(File).
  3. Look at a different pattern. Perhaps I am doing it wrong or trying to accomplish something impossible without knowing more about my requirements? For example some questions would be how is/should the pattern I use interact with the Viewing of the objects and how the user input affects the objects.

These files and folders are really representations of objects on a remote host, they are not acctual files and folders on the hard disk. One user interaction will be when a "file" in the application is dragged onto the desktop, a file is downloaded.

Bonus (some what related) question:
What would be a good trick or technique to cache the files in my application so that if the user does interact with the "virtual" file they see the result faster.

Thank You.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(4

杀お生予夺 2024-10-13 06:31:07

我建议只使用两个类:文件夹和文件。文件夹有两个集合:文件夹和文件。无需用不合适的图案使其复杂化。如果文件和文件夹有一些通用的方法/属性(例如名称),您可以为共享的方法/属性创建适当的接口。

I would suggest simply having two classes, Folder and File. The Folder has two collections, Folders and Files. No need to complicate it with ill-fitting patterns. If Files and Folders have some common methods/properties (such as Name), you can create an appropriate interface for just the shared methods/properties.

雨巷深深 2024-10-13 06:31:07

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

不要无缘无故地尝试使用模式,这只会使事情变得复杂。

I agree with @Brian. I would create an interface with information that exists both for files and folders.

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;}
}

Don't try to use patterns without a reason, will only complicate things.

世态炎凉 2024-10-13 06:31:07

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

Using the composite pattern here is particularly useful if you plan on implementing the visitor pattern with it. In other words, over time you might want to add any number of unforeseen activities on your file/folder structure. For instance, you didn't know you needed the ability to inspect your filesystem for csproj files that contained a reference to EnvDTE or count the number of zero-length files. That is easy with the combination of these two patterns. Sometimes the patterns are useful. Sometimes they go down in history as "it looks like somebody was learning a pattern". Consider the larger business requirements with an engineering trade study. Particularly identify if there is a need for scalability or extensibility and make a decision.

凶凌 2024-10-13 06:31:07

我发现几乎所有使用接口的模式都存在同样的问题。接口方法的调用者无法保证实现者执行特定任务,或者确实执行任何操作。这让我不满意,我不确定我是否知道这个哲学问题的令人满意的解决方案。

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

另一方面,这可以被认为是一种反模式,因为接口的要点是您关心底层实现。这意味着您必须构建代码,以便如果它没有公开预期的行为,则这是实现者的问题,而不是调用者的问题。

I perceive the same problem with almost all patterns that use interfaces. The caller of an interface method has no assurance whatsoever that the implementer performs a particular task, or indeed does anything at all. This dissatisfies me, and I'm not sure I know of a pleasing resolution to this philosophical problem.

One idea I had is to expect every interface method to return an instance of a class - this class should have a private constructor and require certain steps to create it, to 'prove' that the creating method is doing something relevant. It would be like a 'report' of work done that a stranger - which an interface implementer is - can return to the caller for verification.

On the other hand, this could be considered an anti-pattern because the point of interfaces is that you don't care about the underlying implementation. This means that you have to structure your code so it's the implementer's problem if it doesn't expose the expected behaviour, not the caller's.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文