2

我有一个DownloadManager管理多个DownloadItem对象的类。每个DownloadItem都有类似ProgressChanged和的事件DownloadCompleted。通常您希望对所有下载项使用相同的事件处理程序,因此必须为每个DownloadItem.

因此,我需要决定使用哪种模式:

  1. 使用一个DownloadItem作为模板并根据需要克隆它

        var dm = DownloadManager();
        var di = DownloadItem();
        di.ProgressChanged += new DownloadProgressChangedEventHandler(di_ProgressChanged);
        di.DownloadCompleted += new DownloadProgressChangedEventHandler(di_DownloadCompleted);
        DownloadItem newDi;
        newDi = di.Clone();
        newDi.Uri = "http://google.com";
        dm.Enqueue(newDi);
        newDi = di.Clone();
        newDi.Uri = "http://yahoo.com";
        dm.Enqueue(newDi);
    
  2. 相反,设置事件处理程序DownloadManager并将事件复制到每个DownloadItem被排队的事件。

        var dm = DownloadManager();
        dm.ProgressChanged += new DownloadProgressChangedEventHandler(di_ProgressChanged);
        dm.DownloadCompleted += new DownloadProgressChangedEventHandler(di_DownloadCompleted);
        dm.Enqueue(new DownloadItem("http://google.com"));
        dm.Enqueue(new DownloadItem("http://yahoo.com"));
    
  3. 或者使用某种工厂

        var dm = DownloadManager();
        var dif = DownloadItemFactory();
        dif.ProgressChanged += new DownloadProgressChangedEventHandler(di_ProgressChanged);
        dif.DownloadCompleted += new DownloadProgressChangedEventHandler(di_DownloadCompleted);
        dm.Enqueue(dif.Create("http://google.com"));
        dm.Enqueue(dif.Create("http://yahoo.com"));
    

你会推荐什么?

4

2 回答 2

2

为什么 DownloadItems 负责报告进度(从 API 设计的角度来看)?

我想说的是 DownloadManager 负责下载 DownloadItems,因此也负责报告进度。(当然,内部实施策略可能会有所不同。)

我会选择第二个选项:

var dm = DownloadManager
{
    "http://google.com",
    new DownloadItem("http://yahoo.com") { Retries = 5 }
};

dm.ProgressChanged += (sender, e) =>
    Console.WriteLine("Download {0}: {1:P}", e.Uri, (double)e.Progress / 100.0);

dm.DownloadCompleted += (sender, e) =>
    Console.WriteLine("Download {0}: completed!", e.Uri);

dm.DownloadAllCompleted += (sender, e) =>
    Console.WriteLine("All downloads completed!");

dm.Add("http://stackoverflow.com");
dm.DownloadAllAsync();

如果您手头有一份框架设计指南(第 2 版),请查看第 305--312 页(基于事件的异步模式)。

于 2010-05-01T02:25:14.000 回答
1

我会说带有工厂的模板方法模式将是正确的方法。

于 2010-05-01T02:15:59.087 回答