Fields are Globals

April 21, 2010

Everyone knows global variables are bad. They’re bad because they can obscure the path the data takes through the code. You can set a global in one function and read it in another, and it’s not clear that these two functions are passing data between them. It’s more clear to pass the data as function parameters or return values.

And although everyone knows this, they still do it every day in object-oriented programs, except the globals are now called “fields”. Setting a field in one method and reading it in another is just as bad as doing so with a global variable, but because the variable is inside an object on the heap somehow it has become okay. It’s not. It’s just as bad and it should be avoided. You must think of all fields as globals and minimize their use.

Whenever possible, make fields final (in Java) and pass mutable data around through method parameters and return values. This can be hard in Java when returning multiple values, but it’s still better to make a one-off class to hold both values than it is to use fields as a way to pass data around. At least it’s clear how the data is moving through your code.

To be clear, I’m only addressing the case of a single call from a user of a class. If the user calls the class two different times, then clearly a field might be necessary to keep state between the calls. I’m objecting to this kind of code:

public void doSomething() {
    mStatus = OK;
    doSomethingHelper();
    if (mStatus != OK) {
        fail();
    }
}

private void doSomethingHelper() {
    if (problem) {
        mStatus = FAIL;
    }
}

The status could have just been returned from the second method. Here’s a case where the variable could have been passed in:

public void doSomething() {
    mParameter = ...;
    doSomethingHelper();
}

private void doSomethingHelper() {
    if (mParameter == ...) {
        ...;
    }
}

I see the above two patterns distressingly often, and from people who would never dream to do the same thing with a global variable in C.