Reputation: 283355
I have a DownloadManager
class that manages multiple DownloadItem
objects. Each DownloadItem
has events like ProgressChanged
and DownloadCompleted
. Usually you want to use the same event handler for all download items, so it's a bit annoying to have to set the event handlers over and over again for each DownloadItem
.
Thus, I need to decide which pattern to use:
Use one DownloadItem
as a template and clone it as necessary
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);
Set the event handlers on the DownloadManager
instead and have it copy the events over to each DownloadItem
that is enqeued.
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"));
Or use some kind of factory
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"));
What would you recommend?
Upvotes: 2
Views: 179
Reputation: 217411
Why are the DownloadItems responsible for reporting progress (from an API design perspective)?
I'd say that the DownloadManager is responsible for downloading DownloadItems, and therefore also for reporting progress. (The internal implementation strategy may, of course, differ.)
I'd go with the second option:
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();
If you happen to have a copy of the Framework Design Guideline (2nd ed.) at hand, have a look at pages 305--312 (Event-based Async Pattern).
Upvotes: 2
Reputation: 2192
I would say Template method pattern with a factory would be the right approach for this.
Upvotes: 1