Note - Delegation

Event handlers, Delegates, and Commands

Event driven processing is found in almost every user interface, communication subsystem, and is pervasive in the design of operating systems. A model of window event handling for the Windows operating system is shown in the diagram, below.
  1. image file not found

    Windows Event Processing
    Windows Event Handling
    Input device events generate messages, created by their device drivers, which are all routed into a raw input queue. These are dequeued by the window manager and routed to the appropriate window's message queue, e.g., that of the top-most window covering the current mouse coordinates when a mouse button is clicked, for example.

    The UI thread of each window blocks on its message queue until a message arrives. Then, the UI thread routes the message to an event handler. How does that happen? Well, the application program that created the window defined event handlers for the events it wanted to process and registered them with the Windows event dispatching mechanism. Exactly how that happens, from the application point of view, depends on whether the application is using the Windows API or some framework like WPF, WinForms, or MFC to implement its processing.

  2. image file not found

    .Net Delegate Structure
    .Net Event Handling
    Let's identify code that has events to publish as "Publisher" packages, and code that wants to react to those events as "Subscriber" packages. The Publisher creates instance of a class derived from MulticastDelegate and exposes it as a public resource. Its purpose is to hold references to functions called when a specific event occurs. Here, the event is just something that happend in the application code that the designer thinks of as significant. The Publisher part of the code that generates the event invokes its delegate to, in turn, invoke function references it holds to subscriber's event handlers. These references came from subscriber code, during its initialization.

    This apparatus decouples the Publisher and Subscriber. The Publisher doesn't need to know anything about the Subscriber or its event handlers, and the Subscriber doesn't need to know anything about how the event got generated in the Publisher. It only knows that the Publisher exposes a delegate that it promises to call when the event occurs.

  3. image file not found
    Event Triggers Invocation of Invokers Commands
    Command Pattern Event Handling
    The Command Pattern generalizes the notion of a delegate. Actually the Command Pattern was invented first, and oddly, .Net decided to use a less flexible delegate structure.

    The Command Pattern is composed of an Invoker type that plays the same role as the .Net Delegate. However, it binds to a command interface that can be implemented by derived classes to call global or member functions of any desired signature. Since the invoker binds to the interface, the invoker can hold a mix of derived command types and hence call any type of handler. The derived concrete command objects are responsible for acquiring any data necessary to pass to the event handlers in its receiver.

    Think of the library code as Publisher and the client code as subscriber.

Conclusions:

One important design goal for event handling is to decouple event publishers from event subscribers.
  1. .Net Delegates allow the publisher to be entirely ignorant of the subscribers. It doesn't need to know how many nor their types. Subscribers need to know the publisher and its delegate types, but don't need to know any details of how the event generation is implemented.

    Because of the way Delegates are implemented, each Delegate type can hold references to functions with only one specified signature, but that function can be a member of any type.

  2. Command Pattern event handling also decouples Publisher and Subscriber, but in a slightly more flexible way than the .Net Delegate. Since the concreteCommand objects derive from command and are implemented by the Subscriber, their execute methods can hold references to functions of any signature, and the invoker can hold any mixture of concreteCommand objects needed for the application.