Let me preface the discussion by saying that I understand that there is a good reason the globals exist (they go way back).
The following happened on Monday and illustrates one of the problems with globals:
I was making last minute changes to a product. I was setting an Rng variable in the product, but by the time the output code ran, that boolean always had a reverse value. I searched the code for all places that changed that global, but didn't find any that I wasn't already aware of. To temporarily solve the problem I implemented a hack.
Cindy later explained to me why the global seemed to be changing, but no matter; the root problem is globals themselves.
I'm sure you're all aware of all or part of the following, but I wanted to put together a good list of reasons why globals are bad with few exceptions:
- They make the code less modular; in fact they make it anti-modular - everything is tied to the globals.
- When globals are used, it's exponentially more difficult to determine what to change. When all variables are in their own (smaller) object, you can find what needs to change much more quickly.
- Using globals leads to duplicated and unused variables (of which Cindy and I have found several just since I've been here).
- Better memory footprint: more objects, but fewer in memory at any given time.
- Much easier debugging. Even when you have a simple "dummy" member variable with an accessor at least you can set a breakpoint on the accessor and easily track down all callers.
- This from a portion of the coding standards that Rob referenced in a previous post (and another reason to always have accessors even if they're just dummy accessors): "If you avoid exposing fields directly to the developer, classes can be versioned more easily because a field cannot be changed to a property while maintaining binary compatibility. Consider providing get and set property accessors for fields instead of making them public. The presence of executable code in get and set property accessors allows later improvements, such as creation of an object on demand, upon usage of the property, or upon a property change notification."
- They make test driven development (even though we may never actually adopt this) virtually impossible because you can't test objects individually; they all need globals that are manipulated by other parts of the main app.
- For more, see Code Complete | Chapter 13 | 13.3: Global Data.
In the specific case outlined above, I should have added a member variable to the product class and accessed it from the output code (even though it's a little funky to access the product object at that point).