Robert’s Rules of Coders: #2 Avoid Global Variables
Posted by robkraft on August 2, 2015
Global variables are variables that can be accessed from anywhere in the program. It is appropriate to use a global variable when you have a value that is a constant and thus won’t change as the program runs, but it is rarely appropriate to use global variables for values that change while the program is running.
Functions should usually return the same output when given the same inputs. Global variables in functions can cause the function to return different values, making the function less reliable and more difficult to write unit tests for.
In the block of code above, you can see that the value returned from CalculatePrice() is not predictable. In the first case it returned 11.00, but in the second case it returned 10.50 for the same inputs. Here is a second version of the program:
The second version of the program has the following advantages:
- The programmer can see all the factors that affect the TotalPrice. None are hidden.
- The programmer can write unit tests against the CalculatePrice() function more easily.
- Assert.That( CalculatePrice(4, $2.5, 10%) = 11.00)
The problems with using global variables include the following:
- Global variables can be modified from anywhere in the program, making the output of functions using them less predictable
- Rules that you code in one place about setting the value of a global variable may not be adhered to in other places. For example one block of code may do this:
But another block of code in the program may do this:
- A function or component that uses global variables becomes “tightly coupled” to the other components that use the global variable. This entanglement increases programmatic complexity which means the program is probably more difficult to maintain and enhance, and also that it is difficult to replace one component of the program without affecting others.
- In multithreaded programs, global variables may not be thread-safe.
- In some languages, global variables make it difficult to add new components to an existing program because the new component may contain its own global variables with the same name.
When you have an object that you think should be global so that it can be used everywhere, you should probably use Dependency Injection. Don’t be deceived by the Singleton pattern for a global variable replacement because that often becomes just a more complicated version of a global variable.