Thursday, March 10, 2011

Helper Classes, What are they?


Helper classes are made up of all static methods/variables that are designed to be both generic and dynamic, so they can be used over and over again without having to rewrite the code. It is considered a best practice for most programming languages, but I will be showing you examples in Apex.

Example:
This may be a familiar line of code that is littered all over your classes:
if(myString != null && myString  != '')
{
/// DO SOME THING
}

While that isn't wrong, the phrase "Code smarter not harder" come to mind, so instead of the above line everywhere, create a helper Class and add a method like this:
/// <summary>
/// CHECKS IF STRING IS NULL OR EMPTY
/// </summary>
/// <param name="sInValueToCheck">STRING TO CHECK</param>
/// <returns>TRUE IF NOT NULL</returns>
public static boolean CheckForNotNull(string sInValueToCheck)
{
     if(sInValueToCheck != null && sInValueToCheck != '' && sInValueToCheck.toLowerCase() != 'null')
     {
          return true;
     }
     return false;
}

Then back to your code, you would use something like the following:
if(HelperClassName.CheckForNotNull(myString))
{
/// DO SOME THING
}

And yes, you could keep the method in the same class and not create a new one, but it will look a lot cleaner in its own class, plus some other reasons, but the point is: PUT ALL HELPER METHODS IN THEIR OWN CLASS!!


Helper methods generally fall into two classifications, Global and not. Non Global helpers are on the class or project level, and are made of methods that are more task specific, ie designed specifically for the current project / class at hand. For instance, for my ContactCreation class I needed to check if the last-name was passed, and if not use the email address. Since the method is specif for this project, and i wont likely be needing it anywhere else, it wont be a Global helper, I would make a class called ContactCreationHelpers and add it to that.

Example:
/// <summary>
/// DETERMINES IF LAST NAME EXISTS AND CAPITALIZES THE FIRST LETTER OR RETURNS EMAIL
/// </summary>
/// <param name="sInLastName">CONTACT LAST NAME</param>
/// <param name="sInUrlKey">CONTACT EMAIL</param>
/// <returns>LAST NAME OR EMAIL</returns>
public static string findLastNameOrEmail(string sInLastName, string sInEmail)
{
      if(GlobalHelper.CheckForNotNull(sInEmail))
      {
            if(GlobalHelper.CheckForNotNull(sInLastName))
            {
                  return GlobalHelper.CapitalizeFirstLetter(sInLastName);
            }
            return sInEmail;
      }
      return null;
}

Where as Global helpers are much more generic and the methods that belong to them have to meet a much stricter standard, so its kind of like the 'Cool kids club' of Classes.  The CheckForNotNull method above would be a perfect candidate for the Global Helper Class, and it can be overloaded to cover checking other types like Lists or objects. 
Example:
/// <summary>
/// OVERLOADED
/// CHECKS IF SOBJECT LIST IS NULL OR EMPTY
/// </summary>
/// <param name="lstInValueToCheck">STRING TO CHECK</param>
/// <returns>TRUE IF NOT NULL</returns>
public static boolean CheckForNotNull(List<sobject> lstInValueToCheck)
{
      if(lstInValueToCheck != null && lstInValueToCheck.size() > 0)
      {
            return true;
      }
      return false;
}
/// <summary>
/// OVERLOADED
/// CHECKS IF STRING LIST IS NULL OR EMPTY
/// </summary>
/// <param name="lstInValueToCheck">STRING TO CHECK</param>
/// <returns>TRUE IF NOT NULL</returns>
public static boolean CheckForNotNull(List<String> lstInValueToCheck)
{
      if(lstInValueToCheck != null && lstInValueToCheck.size() > 0)
      {
            return true;
      }
      return false;
}

I wont get into depth about what overloaded means but as you can see all three(including the one at the top) have the same method name, and yes the all live in the same Class. But because the signature is different, meaning the types of variables being passed to the method (string, List<string>, List<sobject>) are different, the program knows to use correct one based on what is passed. So now checking for null is even easier since its the same HelperClassName.CheckForNotNull(myVariable) every time, no matter what you need to check. 


When making or updating these helper classes its important to be VERY selective in what you decide to make a 'helper' method, and even more so when it comes to Global helpers. You want to also make sure that before you start using those classes/methods in your code that they are EXACTLY what you need them to be, test code has already been written and all points of failure have been covered. Their should be NO updating, other than to add new or overloaded methods, since doing so would potentially brake any number of classes that may be using it.  


Remember,  code smarter not harder.


Questions? 
Twitter: @SalesForceGirl  or Facebook  





2 comments:

  1. Thanks for the help!

    I would add a little improvement, you should use String.isEmpty() and String.isBlank() methods to validate these kind of conditions:

    (sInValueToCheck != null && sInValueToCheck != '' && sInValueToCheck.toLowerCase() != 'null')

    Regards,

    ReplyDelete
  2. of corse! this is an old entry, written long before they added those string methods :-)

    ReplyDelete