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.



No comments:

Post a Comment