Thursday, 12 July 2012

Delegates and Events


The audio blog is here
Delegation :
                    Delegates mean those who are responsible. Delegation is handing over the responsibility a particular class to some other class. This lets objects to follow the single responsibility principle. If too much responsibility is being added to the class , you can delegate the responsibility to another class.
          

Delegates and Events:
                  In programming delegates are classes that have the responsibility to handle particular events. An event can range from a key stroke to a system call due to some internal errors. To simplify the explanation of delegates to a simple form you can relate the Delegates to function pointers in C.
              A typical delegate has a signature. The syntax of a delegate is,
              Delegate return_type Delegate_name(input type1,.....)
              The signature of the delegate is the return type and the input parameters.
              for example,
              public Delegate int my_first_delegate(int,int ) is a delegate. It can have functions that returns an int and gets two integer parameter.

                Example 1:
                  int add(int a,int b)
                   {
                          // do addition and return the value
                    }
                  public Delegate int my_first_delegate(int,int ) ;
                  my_first_delegate first=new my_first_delegate(add)
         
              Here you can call the add method using, first.invoke(10 ,20 );

Why Delegates ?
          Delegates came into existence because of various things. They came to handle the events when an event is getting triggered. They are also used in abstracting the user from  having the entire working section of code onto the client side.
          Consider the call add( 20  ,30 ) being made from the client side. If you have deleted the method on the server. The client will be reported with an error. To prevent such things we may use a Delegate. The generic pointer with the signature described in the previous example can be declared and used.
         If many functions are declared and the function to which the call has to be made can be changed dynamically. Consider the following example,
             
             public class list_function
             { 
                    public delegate int two_functions(int i, int y); 
                    public PointerMaths getPointer(int intoperation) 
                   { 
                         two_functions objpointer = null; 
                          if (  intoperation == 1  ) 
                         { objpointer = Add; } 
                          else if (  intoperation == 2  ) 
                         { objpointer = Sub; } 
                          else { objpointer=Print_list_the_functions_available; } 
                           return objpointer; 
                    }
                   private int add(int a,int b)   
                   {
                         return a+b;
                    }
                   private int sub(int a,int b)   
                   {
                         return a-b;
                    }
                     private int Print_list_the_functions_available(int a=0,int b=0)
                      {
                            print "1-->ADD , 2-->SUB , only two choices are available";
                            return -1;
                       }
               }
           In the client side of the code will be something like this,

            list_function ls=new list_function();
            int temp = ls.getPointer(3) .Invoke();
            int result = ls.getPointer(1).Invoke(30,20);

          The above code will result in addition function getting invoked.

Multicast Delegates :
           There are some times when more than a function are needed to be coupled to the delegate.
            Consider a scenario when a building is in fire, you will need a automated system to start showers inside the building , raise an alarm, stop elevators, make a call to the nearest fire engine service.
           All these functions are coupled one after another. This can be done using a multicast delegate.
            E.g :
             public void handle_fire_breakout();
             handle_fire_breakout hfr = null;
             hfr += start_shower();
             hfr += raise_alarm();
             hfr += stop_elevators();
             hfr += call_fire_engine();

            if the hfr is being called from the monitoring client side it may get called using ,
              in_case_of_fire.get_pointer().Invoke();

           The above mentioned methods will execute sequentially in the order by which they were added to the delegate.
            There are certain disadvantages in multicast delegates. If the methods which are getting invoked by the delegate eg. start_shower() belonged to another class called Shower then a problem  occurs. The delegate will be calling the method of another object(Shower) without even asking for the objects approval.
           If we put it in another way i.e, if the delegates are within the class Shower it will be a problem. Because the class shower will have the complete authority over the delegate and it can add any function over the delegate which is undesirable.
          To overcome these concepts we move on to the concept of events.

Events :
       Events will be assigned a listener of the events and the listener can add themselves to be the listener of the particular event. Thus overcoming both the problems described earlier.
        So how to accomplish the previous fire_monitoring thing using events. We shall see now,
        Class Shower // event_handler
        {
                 Shower(Fire_control fc)
                 {
                       fc.hfr_new += new handle_fire_breakout(start_shower); // assign event to a listener
                  }
                  private static start_shower()
                  {
                      // make the shower pour water
                   }
         }
         Class Fire_control
         {
                  public void handle_fire_breakout();
                  void execute ()
                  {
                      event  handle_fire_breakout hfr = null ; // event in the class
                       hfr += raise_alarm();
                       hfr += stop_elevators();
                       hfr += call_fire_engine();
                      if(fire_arises())
                      {
                             hfr();  //calling the event makes the listener start_shower
                      }
                   }
                   raise_alarm() {....}
                   stop_elevators() {...}
                   call_fire_engine() {...}
          }
          Class main_
          {
                  Fire_control fc= new Fire_control();
                  Shower(fc);
                  fc.execute() ;
           }
          This makes the event getting triggered in the Fire_control class will be listened by the start_shower function method of the Shower class.

No comments:

Post a Comment