mpen
mpen

Reputation: 283355

Repeated properties design pattern

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:

  1. 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);
    
  2. 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"));
    
  3. 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

Answers (2)

dtb
dtb

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

Prashant
Prashant

Reputation: 2192

I would say Template method pattern with a factory would be the right approach for this.

Upvotes: 1

Related Questions