接口的最佳实践,允许添加,删除等子对象与广播事件(类似于ObservableCollection)

时间:2014-03-26 11:05:23

标签: c# design-patterns interface

我试图为文件夹指定界面。该接口应该允许 - 添加或删除IFile类型的文件 - 获取IFile列表 - 每当添加/删除/更改文件时广播事件(例如,用于GUI订阅)

我试图找到最佳方法。到目前为止,我提出了三个想法:

1

public interface IFolder_v1
{
    ObservableCollection<IFile> files;
}

2

public interface IFolder_v2
{
    void add(IFile);
    void remove(IFile);
    IEnumerable<IFile> files { get; }

    EventHandler OnFileAdded { get; }
    EventHandler OnFileRemoved { get; }
    EventHandler OnFileDeleted { get; }
}

3

public interface IFolder_v3
{
    void add(IFile);
    void remove(IFile);
    IEnumerable<IFile> files { get; }

    EventHandler<CRUD_EventArgs> OnFilesChanged { get; }
}

public class CRUD_EventArgs : EventArgs
{
    public enum Operations
    {
        added,
        removed,
        updated
    }

    private Operations _op;

    public CRUD_EventArgs(Operations operation)
    {
        this._op = operation;
    }

    public  Operations operation
    {
        get
        {
            return this._op;
        }
    }
}

Idea#1似乎非常好实现,因为它不需要很多代码,但有一些问题:例如,如果IFolder的实现只允许添加特定类型的文件(比如说,文本文件) ,并在每次添加另一个文件时抛出异常?我不认为使用简单的ObservableCollection是可行的。

创意#2似乎没问题,但需要更多代码。此外,定义三个单独的事件似乎有点乏味 - 如果一个对象需要订阅所有事件怎么办?我们需要为此订阅3个不同的事件处理程序。好像很烦人。 也比现在的解决方案#1更容易使用,需要调用.Add来添加文件,但是文件列表存储在.files等中 - 所以命名约定比捆绑所有内容要简单得多在一个简单的子对象中(。#1中的文件)。

Idea#3规避了所有这些问题,但代码最长。另外,我必须使用一个自定义的EventArgs类,我无法想象在接口定义中特别干净? (对于简单的CRUD事件通知,定义一个类似乎也有些过分,不应该有某种类型的现有类吗?)

对于您认为最佳解决方案的一些反馈意见(甚至可能是我根本没想过的东西)。有没有最好的做法?

3 个答案:

答案 0 :(得分:0)

查看框架FileSystemWatcher class。它几乎可以满足您的需求,但是如果您仍然需要实现自己的类,您可以通过查看它的实现方式来获取想法(这与您的#2方法类似)。

话虽如此,我个人认为#3也是一种非常有效的方法。如果结果比使用更短的代码更可读和可维护,不要害怕编写长代码(当然在合理的限度内)。

答案 1 :(得分:0)

就个人而言,我会选择#2。

在#1中,您只需公开整个对象集合,允许每个人对它们做任何事情。

#3对我来说似乎不那么自我解释了。虽然 - 我喜欢在编码时保持简单,所以我可能会有偏见。

答案 2 :(得分:0)

如果观察者的寿命比被观察者短,我会避免发生事件。 ObservableCollection示例的模式,其中集合为订阅的观察者提供了可用于取消订阅的IDisposable对象,这是一种更好的方法。如果你使用这样的模式,你可以让你的类持有一个弱引用(可能使用&#34; long&#34;弱引用)到订阅对象,这反过来会持有一个强引用(可能是一个委托)订阅者和识别它的弱引用。因此废弃的订阅将被垃圾收集器清理干净;订阅者有责任确保订阅对象存在强根引用。

除了废弃的订阅可以清理之外,使用它的另一个好处 &#34;一次性订阅对象&#34;方法是取消订阅可以轻松实现无锁和线程安全,并且可以在恒定时间内运行。要处理订阅,只需将其中包含的委托清空即可。如果每次添加订阅的尝试都会导致订阅管理器检查几个订阅以确保它们仍然有效,则现有的订阅总数将永远不会增长到最后一个垃圾回收的有效数量的两倍以上