The structure of the repeating property pattern

I have a class DownloadManager

that manages multiple objects DownloadItem

. Everyone DownloadItem

has events like ProgressChanged

and DownloadCompleted

. Typically you want to use the same event handler for all loaded items, so it's a little annoying to have to set event handlers multiple times for each DownloadItem

.

Thus, I need to decide which pattern to use:

  • Use one DownloadItem

    as a template and clone it if needed

        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 event handlers to DownloadManager

    and copy events to each DownloadItem

    one that is enqueued.

        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?

+2


a source to share


2 answers


Why are DownloadItems responsible for reporting (in terms of API design)?

I would say the DownloadManager is responsible for downloading the DownloadItems and therefore also for reporting. (Of course, the internal implementation strategy may differ.)

I would 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 have a copy of the Framework Design Guide (2nd ed.) On hand, see pages 305-33 (Event-Based Asynchronous Pattern).

+2


a source


I would say that a Template template with a factory would be the right approach for this.



+1


a source







All Articles