Click here to Skip to main content
Click here to Skip to main content

Tagged as

Delegates Are Good, and Good For You

, 29 Aug 2011 CPOL
Rate this:
Please Sign up or sign in to vote.
Using a delegate could pull your butt out of the fire when you don't want to refactor code to add functionality.
Have you ever been in the situation where you have a considerable base of existing code, and you need to add functionality, but you simply don't have the time to refactor all of the code to explicitly support the desired functionality? I'm sure anyone here with more than a few years of experience can answer "yes" to that question.
 
Today, I was faced with just such a situation. I'm working on a Silverlight app that displays a page on a button press. This page displays one of dozens of available views (depending on the button that caused the page to be displayed), and each view contains a collection of panels that display various data items. The panels can be manually expanded - or "zoomed" - by the user to consume the entire viewable area. The data for the panels may or may not be available, meaning that one or more of the panels would essentially be empty (or display a message saying no data is available). In that event, we want to automatically expand the panel that DOES contain data.
 
The best way (I think) to do this would be to change the constructor for the various chart views (there are several already implemented), but that could possibly cause problems with what is already expected, thus slowing development by everyone involved. I had to come up with a different solution, and the result is my tip.
 
I used a delegate. Delegates are kind of scarey for new programmers, but they're a godsend when you need a quick fix that doesn't require extensive changes to method/constructor parameter lists and such.
 
First, I came up with the method in my parent class:
 
public void ZoomPanelFromView(PanelType panel)
{
    // The methods called here already exist and are event handlers for when 
    // the user clicks one of the associated zoom buttons.
    switch (panel)
    {
        case PanelType.Main       : zMain_MouseLeftButtonUp(null, null); break;
        case PanelType.Ahead      : zAhead_MouseLeftButtonUp(null, null); break;
        case PanelType.AlibiTrend : zTrend_MouseLeftButtonUp(null, null); break;
    }
}
 
Next, I declared a globally accessible delegate that implemented the prototype for the method I was trying to "expose" from the parent class.
 
public delegate void PanelZoomer(PanelType panel);
 
Then, I declared a data member in a static class that I use for globally accessible methods and data members:
 
public class Globals
{
    // this delegate allows the chart classes to callback to the parent page and 
    // zoom the specified  panel
    public static PanelZoomer PanelZoom;
 
    public static Globals(){}
}
 
Now, with all of the pieces in place, I could set it in the parent class:
 
Globals.PanelZoom = this.ZoomPanelView;
 
...and use it from my view class that knows nothing of the parent page:
 
    if (Globals.PanelZoom != null && m_dataPoints.Count == 0 && string.IsNullOrEmpty(m_data.textData))
    {
        Globals.PanelZoom(PanelType.Main);
    }
 
My solution didn't break anything, and requires no regression testing beyond making sure the user can still manually zoom the panels. Because I check for nullness on the delegate, I'm ensuring that the delegate has been set before using it. Everyone's happy, nobody has to change what they're doing or have already done with regards to the code already written, and we're free to add an overloaded constructor at our convenience. For the record, this is the only reason so far that the view class would have to know about the parent page at all, and IMHO, this doesn't warrant creating an overloaded constructor that allows the page to pass a pointer to itself to the view.
 
Yeah, I acknowledge that this breaks pretty much any OOP rule you might mention, and a band-aid like this is probably not the best solution, but the realities of working in a production environment are the biggest contributing factors of what you can and cannot implement when you're on a schedule.
 
I view OOP rules (and pretty much any other stuff you might consider to be a rule) as mere guidelines of things you SHOULD do, not what you MUST do. Finally, as long as your code is well documented (INCLUDING the *why-I-did-it" AND "where-I-did-it" behind the code), maintenance programmers can easily follow and modify your code without any problems at all.
 
There are a couple of additional tips here. Don't be rigid in your compliance with "industry standards", and be ready to look at a problem from different angles.
 
EDIT (29 Aug 2011) ================
 
Fixed some glaring typos.

License

This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)

Share

About the Author

John Simmons / outlaw programmer
Software Developer (Senior)
United States United States
I've been paid as a programmer since 1982 with experience in Pascal, and C++ (both self-taught), and began writing Windows programs in 1991 using Visual C++ and MFC. In the 2nd half of 2007, I started writing C# Windows Forms and ASP.Net applications, and have since done WPF, Silverlight, WCF, web services, and Windows services.
 
My weakest point is that my moments of clarity are too brief to hold a meaningful conversation that requires more than 30 seconds to complete. Thankfully, grunts of agreement are all that is required to conduct most discussions without committing to any particular belief system.

Comments and Discussions

 
GeneralYou "suspect"? This is precisely one of the uses for delegat... PinmvpJohn Simmons / outlaw programmer16-Nov-10 10:15 

General General    News News    Suggestion Suggestion    Question Question    Bug Bug    Answer Answer    Joke Joke    Rant Rant    Admin Admin   

Use Ctrl+Left/Right to switch messages, Ctrl+Up/Down to switch threads, Ctrl+Shift+Left/Right to switch pages.

| Advertise | Privacy | Mobile
Web03 | 2.8.141022.2 | Last Updated 29 Aug 2011
Article Copyright 2010 by John Simmons / outlaw programmer
Everything else Copyright © CodeProject, 1999-2014
Terms of Service
Layout: fixed | fluid