Use of Action (Function programming) for better code health continued

Please read Part 1 of this post here.

But with the following code I can just do away with making change only to one place.

Class HandelException {
 function HandleError(Action success,
Action <Exception> fail, Action final){
 try{
 sucess();
 }
 catch(Exception e){
 Log(e.Message);
 fail();
 }
 finally{
 final();
 //Do some funky stuff here;
 }

 }
}

Class A {
 int i;
 int j;

 function Add(int arg1, int arg2)
 {
 //Comment:
 HandelException.HandleError(sucess,fail,final);
 HandelException.HandleError(
 () => {return arg1 + arg1;}, //success
 (e) => {RaiseException(
  "Addition Failed in Add()"); }, //fail
 () => {/* clean up code */} //final
 )

 }

 function Sub(int arg1, int arg2)
 {
 () => {return arg1 - arg1;}, //success
 (e) => {RaiseException(
"Addition Failed in Sub()"); }, //fail
 () => {/*clean up code*/} //final
 }
}

See the magic here… we are not passing any parameters to the handler class.

  • We just provide the function parameters that we might want to use in the consuming (Class A) class.
  • We might want to use the exception (here -> e parameter for fail action)  for propagating user friendly message to higher layers)
  •  Now Class A concentrates more on its given responsibility (do some Math work) than the other clattery codes. It’s easy to spot logic errors there.
  •  Let say if we want to audit log all the calls to methods. Just add a logger statement before and after  sucess()  in HandelException.HandleError -> Try Block that will do the trick.

Hope this serves the purpose of explaining the use of <actions>. There are more things to it will cover it some other time.

Use of Action (Function programming) for better code health

One of my friend Kritul Rathod had gave his understanding of Action keyword in C#.

Passing the functions as parameters helps in many ways, here are basic ones

  • It helps separate the coding logic (for some trivial things like exception handing, type conversions, Verbose Logging, etc – the things that clutters the code) from the actual class implementation.
  • Since the ‘Actual Function Implementation’ stays in the same class, only its invocation logic is delegated to a separate class. so there is no need to pass a “Train” of arguments in function calls hence less future code changes .

To explain the logic behind the exception handling just have a look at the following code.

Class A
{
 int i;
 int j;

 function Add(int arg1, int arg2)
 {
 try{
 return arg1 + arg1;
 }
 catch(Exception e){ {
 Log(e.Message);
 }
 finally
 {
 //Do some funky stuff here;
 }
 }

 function Sub(int arg1, int arg2)
 {
 try{
 return arg1 - arg1;
 }
 catch(Exception e){
 Log(e.Message);
 }
 finally{
 //Do some funky stuff here;
 }
 }
}

Now for some great reason let’s say we make change to the Log method and pass one extra for passing actual exception object. We would need to do change in all classes using this method.

Please read part 2 of this post here.