Friday, March 11, 2016

Static V. Instance, or, How Can A Variable Be Unchanging?

I asked my Auntie Pat Tern why she loves to watch Jeopardy! and she said, "if I watch it enough, I will see answers to all the questions in the world." So I looked through the questions that my developers ask to see if they could be answered by Jeopardy!

One of the questions that comes up frequently is whether use of the 'static' keyword is an antipattern or whether it is best practice. Of course, if it's used wrong, it is an antipattern, so understanding static versus instance methods, variables and initialization code is important.
Final Jeopardy! means there won't be
infinite answers this time.

Taking Jeopardy! as our example, the classic game show that contestants win by providing the most correct responses, we can see that some things don't change from week to week. The show's name, the show's host, these are constants and so of course are static because "static" means unchanging. A static response can be provided for questions about the host and show name.

Every show has three contestants and to create a show, its producers need to know who the three contestants will be. So they conduct tryouts to choose and schedule competitors. The names of the competitors change from night to night, so the list of competitors is variable, but show producers have to know who is scheduled before the show is created, so it is a static variable. A static response can be provided to the question of who will be the competitors for any specified date.

When the show is filmed, the responses that one contestant provides as part of the action of the show are defined by the instance of the show and depend on the inputs the contestant receives from the show and the interactions the contestant has with other contestants on that particular show. So these responses are non-static and depend on the instance of the show.

As an example let's consider three possible questions about the upcoming Jeopardy! college championship round:
  1. Who's the host? We expect one answer: 'Alex Trebek'. 
  2. Who are the competitors? We expect one answer: the three college students, depending on who is chosen for a specified day. 
  3. What is the contestant's 'question' and score for the first input in the first category? The response to this question depends on actually seeing the college championship round in action, knowing what the inputs are and seeing which contestant acts first and the result of that particular action.  
So the first two are static and the last one non-static and specific to its instance.  

In Apex, you can see an example of static vs. instance in the Date class. This class offers both static and instance methods. Let's consider three possible questions we could ask today:
  1. What is the date today? We expect one specific answer for this question and it doesn't need any additional information for us to ask it: Date.today().
  2. Is it a leap year? We expect only one answer for this question, depending on a specified year, for example: Date.isLeapYear(2016); or Date.isLeapYear(2023);.
  3. What is the year? The response depends on knowing the date in question -- we need an instance of Date in order to figure out the year of that specific date, for example: Date yearLater = Date.today().addYears(1); Integer nextYear = yearLater.year();.
Again, the first two are static methods while the third, determining the year, is specific to its instance. You might wonder, for example, what happens in Apex when you add a year to a leap day, will Apex give us February 28 or March 1 of the next year (or null)? You could run the following code to create an instance specific to a leap day and test it out:

The above code primarily uses instance methods, but using the 'static' keyword in Apex can be particularly useful when it comes to writing code called by Triggers. Since a single Trigger can result in a cascade of other Triggers firing, we may need to keep track of some information across all the business process automation associated with the cascade of Triggers. Having a separate class with a static method or variable for all of the Triggers allows us to share specific data across the code executing for multiple Triggers.

For example, a separate class that contains a static variable can indicate the number of times a particular automation has run to help avoid an infinite recursion

Infinite recursions need to be avoided in code, but Auntie Pat Tern may be correct that infinite episodes of Jeopardy! will contain all the answers to all the questions in the world.



Friday, March 4, 2016

Start Documenting Rather Than Accepting "No Comment"

My Auntie Pat Tern tried to convince my cousin Tim Toady that he should be using the 3/5 rule of essay writing he'd been taught -- three ideas, five paragraphs -- but, as usual, Tim insisted there is more than one way to do it (TIMTOWTDI). So I looked through the code in my Salesforce org to see if my developers were following the 3/5 rule for comments or if TIMTOWTDI had gotten into our code.  Unfortunately, I mostly found code with no comments at all.

Code without comments is like a research paper without a thesis statement to detail its purpose.  It's like doing something over and over without understanding why because comments should always clarify why it does what it does.  It's like burying treasure without leaving a proper map because good comments point to valuable resources the code uses or makes available.

Code comments should follow the 3/5 rule of comments:  there are three places where comments should occur and five specific topics that need to be addressed.

The three places where comments should be found in Apex code are:
  1. Block comments at the beginning of classes.
  2. Block comments at the beginning of methods.
  3. Line level comments for constants, loops, conditions, and where clarification is possible.
The five topics that should always be found in block comments are:
  1. Description of purpose and assumptions.
  2. Author/date for creation and modification.
  3. Parameters for methods that accept values, or none.
  4. Return values for methods that pass values, or none.
  5. References and dependencies.
Here's an example of code that follows the 3/5 rule of comments:



In this example, block comments appear at the start of the class and at the start of the methods while inline comments appear within methods and for named constants. The comments use Javadoc tags like "@description" to make the important topics easy to locate.  These comments even include "TBD" to indicate code that is incomplete and point out the limitation imposed by the choice of Integer as a data type rather than Long. Comments should always include information that may be reconsidered during the next phase of development.

We ask that developers and admins both be responsible for code comments because the admin should know how code effects data integrity and user experience.  Without that level of cooperation and understanding, admins have been known to implement validation rules that cause code to fail and developers have been known to implement code that causes user experience to decline.

Tim Toady is right, there is more than one way to do it with code.  That's why we ask for comments that explain why the code was written the way it was.  And we follow Auntie Pat Tern's 3/5 rule to make sure we have comments in three areas of code and covering 5 required topics.  Better comments lead to better collaboration and easier maintenance of the code and the org where it runs.