Globals aren't that bad. As stated in several other answers, the real problem with them is that what is, today, your global folder path may, tomorrow, be one of several, or even hundreds. If you're writing a quick, one-off program, use globals if it's easier. Generally, though, allowing for multiples even when you only think you need one is the way to go. It's not pleasant to have to restructure a large complex program that suddenly needs to talk to two databases.
But they do not hurt reliability. Any data referenced from many places in your program can cause problems if it changes unexpectedly. Enumerators choke when the collection they're enumerating is changed in mid-enumeration. Event queue events can play tricks on each other. Threads can always wreak havok. Anything that is not a local variable or unchangable field is a problem. Globals are this sort of problem, but you're not going to fix that by making them non-global.
If you are about to write to a file and the folder path changes, the change and the write need to be synchronized. (As one of a thousand things that could go wrong, say you grab the path, then that directory gets deleted, then the folder path is changed to a good directory, then you try and write to the deleted directory.) The problem exists whether the folder path is global or is one of a thousand the program is currently using.
There is a real problem with fields that can be accessed by different events on a queue, different levels of recursion, or different threads. To make it simple (and simplistic): local variables are good and fields are bad. But former globals are still going to be fields, so this (however critically important) issue does not apply to the Good or Evil status of Global fields.
Addition: Multithreading Problems:
(Note that you can have similar problems with an event queue or recursive calls, but multithreading is by far the worst.) Consider the following code:
if (filePath != null) text = filePath.getName();
If filePath is a local variable or some kind of constant, your program is not going to fail when running because filePath is null. The check always works. No other thread can change its value. Otherwise, there are no guarantees. When I started writing multithreaded programs in Java, I got NullPointerExceptions on lines like this all the time. Any other thread can change the value at any time, and they often do. As several other answers point out, this creates serious problems for testing. The above statement can work a billion times, getting it through extensive and comprehensive testing, then blow up once in production. The users won't be able to reproduce the problem, and it won't happen again until they've convinced themselves they were seeing things and forgotten it.
Globals definitely have this problem, and if you can eliminate them completely or replace them with constants or local variables, that's a very good thing. If you have stateless code running on a web server, you probably can. Typically, all your multithreading problems can be taken on by the database.
But if your program has to remember things from one user action to the next, you will have fields accessable by any running threads. Switching a global to such a non-global field will not help reliability.
5you can use a config class that handles access to those settings. i think its good practise to have one and only one place where configuration settings are read from config files and / or databases while other objects fetch them from that config thing. it makes your design more clean and predictable. – Hajo – 2012-05-10T19:37:49.663
15Where's the difference with using a global? Your "one and only one place" sounds very suspiciously like a Singleton. – Madara Uchiha – 2012-05-10T19:39:25.617
you can also have a config object factory or config proxy object, its up to you how this is done. it makes you able to seperate configuration stuff from other parts. – Hajo – 2012-05-10T19:40:42.357
3"for instance system folder paths, or application-wide database credentials ..." storing credentials is a separate topic, but if the settings are read-only, and I mean read-only, then this is fine. In fact, Visual Studio lets you generate settings that are global to the application. if the settings can change, then that is a totally different story .... by the way, dependency injection is an OOP concept. To truly understand why global state is evil, you need to drink some functional koolaid. I recommend pragmatic sources, such as SICP or some Clojure lectures. – Job – 2012-05-10T20:12:00.017
Also see this discussion: http://stackoverflow.com/questions/1392315/problems-with-singleton-pattern
– Andrew Shepherd – 2012-05-11T06:22:08.82085The only real evil are dogmas. – Pieter B – 2012-05-11T06:49:31.053
1
@MadaraUchiha There is an excellent google tech talk - https://www.youtube.com/watch?v=-FRm3VPhseI
– Dexters – 2013-09-29T18:27:03.6638Using global state with your fellow programmers is like using the same toothbrush with your friends - you can but you never know when someone will decide to shove it up his bum. – ziGi – 2015-05-15T14:20:17.730
The devil is evil. Global state is neither evil or good. It can very useful or harmful depending on how you use it. Don't listen to others and just learn how to program properly. – annoying_squid – 2016-03-02T16:37:34.320
@annoying_squid Please read the first sentence of the question :) – Madara Uchiha – 2016-03-02T16:38:07.890
Even immutable global state can be changed by a programmer when requirements change. I like to be able to see what effects a change will make before I make it, which means reading all of the code that depends on what I'm changing. If I change a local variable, I read the whole function. If I change a private variable, I read the whole class. If I change that global system folder path, I'm out of luck unless I have time to read the entire program. – Andrew Piliser – 2016-05-24T17:54:28.483