Monday, August 24, 2009

Member Variables are not Global Variables

It is widely accepted that global variables, in almost any context, are a bad practice. But there is a common practice that leads to code that is harder to maintain - the use of member variables for passing information between functions for a particular set of functionality. This is a subtle way of creating global variables in that they are "global" between functions.

As an example, let's look at the code below. For this example, we're going to assume that "memberVariable" is not used anywhere else but "DoA()" and "DoB()".

private bool memberVariable = false;

public void MainFunction()
{
DoA();
DoB();
}

private void DoA()
{
// do some stuff

if(something)
memberVariable = true;
else
memberVariable = false;

// maybe do something else
}

private void DoB()
{
// do some stuff

if(memberVariable)
DoOneThing();
else
DoAnother();

// do more stuff
}



Member variables are used for maintaining the state of the particular object. But as can be seen in this case, "memberVariable" does not contain state. It contains a flag that is particular to the logic of "MainFunction()". This is a bad practice because it is very hard to know what "DoB()" is going to do without also examining "DoA()". If this were expanded further and the class had many functions, it would be difficult to know who uses "memberVariable" how and why.

There are a number of ways to refactor this code to change the use of "memberVariable". DoB() could take memberVariable as a parameter or retrieve it's value by calling another function. Even though there are different ways to alleviate the problem, the idea is the same. Functions should be autonomous and not require other functions being executed in order to work properly. And even if a "global" variable is only global to two private functions, it's still global.

No comments:

Post a Comment