50

For desktop application that is. This is just a general question that maybe only need general answers.

Guge
  • 4,569
  • 4
  • 35
  • 47
mhd
  • 4,561
  • 10
  • 37
  • 53
  • 1
    i'm sorry this feels like a candidate for closing, unless you change it to say what's your q actualy – Johannes Schaub - litb Dec 13 '08 at 14:35
  • 6
    Did I type anything wrong ?Sorry, I don't understand why you want to close this questions. All I was asking was just a general programming question. – mhd Dec 13 '08 at 15:36
  • 1
    I think your question is fine. If you don't read it very carefully, it seems slightly belligerent (words like "condemned" and "despised" produce that effect), but you're realy just asking about best practices. – MusiGenesis Dec 13 '08 at 15:42
  • On this other hand, this is probably a duplicate question, but I like Corey's answer so I'll leave it open. :) – MusiGenesis Dec 13 '08 at 15:43
  • what i mean is that he said "globals are condemned (well, i think most will agree), and singleton is despised (well i think most will *not* agree)". i would have liked to hear why he thinks so. instead he just waited for answers to that statement, leaving us in dark about that opinion. – Johannes Schaub - litb Dec 13 '08 at 15:57
  • i'm aware i did the same with my comment above :) now i completed it to state my objections. i apologize :) – Johannes Schaub - litb Dec 13 '08 at 15:58
  • 3
    litb: I think most people *should* agree about singletons. They're just globals with additional difficulties added in. If you have to use global data, just make it global. No point in insisting on adding additional fake requirements like "single instance", which is never actually true in practice. – jalf Dec 13 '08 at 18:30
  • I just hate the mods that always want to close every single god damn question. Where are people suppose to ask some of the specific day to day questions if all you guys want is a abstract question that could be answers like 1+1=2? Everytime, I google a good question asked on StackOverFlow, it's freaking "closed", or "off topic" or what ever! – Louis Hong Jan 15 '15 at 00:42
  • My opinion is: Singleton is better than global variable for one single reason: ownership. Most software developement are divided by functionality, and global variable (a data structure) often does not have clear ownership, and can be modified by different parties, causing conflicts. By wrapping a class over the global static variable (singleton), it becomes part of an interface that is owned by someone. – NeoWang Apr 21 '17 at 01:58

9 Answers9

41

A static class with static data members? But who cares. Static data members are just global variables with more politically correct packaging.

Don't let fashion override your common sense. There's nothing wrong with using a plain old global variable. The singleton pattern is often overkill and annoying to type, and annoying when you are single stepping through code to debug it.

Assuming you are using C/C++, I would recommend that you not have global variables that are class instances that allocate memory from the heap. They will make it harder for you to use tools that check for memory leaks. Declare the global as a pointer, new it at the beginning of main(), delete it at the end.

EDIT AFTER 6 COMMENTS: Think of logging. Wouldn't you want to be able to write a line to your log from anywhere in your app? How concretely do you accomplish that without there being something globally visible to do that logging? If you want something globally visible, then go ahead and make it globally visible.

Corey Trager
  • 22,649
  • 18
  • 83
  • 121
  • Coming from .NET I agree - static variables for classes. This provides a nice enough organization for you global variables. :) – Vilx- Dec 13 '08 at 14:46
  • Fashion? Global variables have been condemned for decades, and for good reasons. But I agree that singletons and class variables are the same thing. – Nemanja Trifunovic Dec 13 '08 at 14:57
  • 1
    It should be pointed out that static members don't actually solve the problems that globals present. The reasons why globals are seen as bad also mostly apply to static members. – Mike Burton Dec 13 '08 at 15:51
  • 2
    no. globals are seen as bad because of their bright scope. but that isn't true for neither other free objects in non-global namespace, nor for static class members – Johannes Schaub - litb Dec 13 '08 at 17:10
  • Sorry, but no, that's not the only reason they're seen as bad. They're prone to bad behaviour and general mishandling. The issue of "bright scope" has never come up in any discussion of the topic in which I've participated. – Mike Burton Dec 13 '08 at 17:21
  • yes that's not the *only* reason, but THE reason they are bad. there are language specific reasons like in C++ the order of construction or destruction. – Johannes Schaub - litb Dec 13 '08 at 17:41
  • As I said, it's never come up in my experience. It's certainly not THE reason in my professional circle. – Mike Burton Dec 13 '08 at 18:21
  • What about logging? Which log? In some cases I certainly *don't* want it to be global I may want to pass different logs to different objects. I may have different instances of logs. I used to use global logs, which became a major problem in an application we made a while back. – jalf Dec 13 '08 at 18:27
  • 5
    But of course, sometimes you may still want a global log. Which is why I feel it's not globals as such that are bad, but *global mutable state*. A log may be global if it's not mutable state. If it just takes text and throws it out to some external medium, it's fine. But not all logs are that simple – jalf Dec 13 '08 at 18:28
  • The logging question is a red herring anyways - there may well be a globally-accessible "hook" to the logging system, but that's not at all the same as a global variable. Currently I use service locators to hook log systems. This allows me to readily change out the logger for different situations – Mike Burton Dec 13 '08 at 19:13
  • Logging is almost the only true place a Singleton should be allowed – mmcdole Dec 13 '08 at 20:00
  • 7
    Regarding "Logging is almost the only true place a Singleton should be allowed", what about configuration? I mean, getting settings from a configuration file? The app reads/loads the file at startup and then makes the values readable from anywhere in the app. – Corey Trager Dec 15 '08 at 00:34
  • Regarding "global mutable state" being bad, what about a flag that registers whether there is dirty, unsaved data, so that you can prompt the user if he tries to close the app that there is unsaved data? – Corey Trager Dec 15 '08 at 00:36
  • 2
    Globals are like GOTOs - very usefull tools in the hand of professionals and the banning of them came from historic times where things were not comparable (like eating pig meat in the desert without fridges - and the debate here is just as religious). – Lothar Aug 28 '16 at 13:24
21

Answer depends on the language. I recently met a guy whose company develops the USB stack that runs on many popular cell phones (e.g., so your phone can talk to your computer). They have a rule in their shop that all C procedures must be reentrant. In practice what this means is that instead of global variables, they use an extra parameter to each routine; the parameter points to the state that should persist between routines.

I use this technique all the time for abstractions with state. Example: reader abstraction for photographic images: reader provides access to one pixel at a time; it must know open file descriptor, what is the current position in the image, so on and so forth. All that information goes into a private C struct or the private members of a C++ class. No global variables. The outside world sees:

typedef struct Pnmrdr_T *Pnmrdr_T;

struct Pnmrdr_T *Pnmrdr_new(FILE *);
pixel Pnmrdr_get(Pnmrdr_T);
void Pnmrdr_close(Pnmrdr_T);
void Pnmrdr_free(Pnmrdr_T *rp); // frees memory and sets *rp = NULL

This style of programming is very similar to OO methods.

Why better than global variables? There are no surprises. If something goes wrong or you want to add a feature, you know that everything is explicit in values passed in. Moreover, you know you can plug lots of modules together and they won't interfere unless you explicitly pass state between them. My contact in the cellphone biz says this property has been huge for his company---they're an OEM software outfit and they can easily plug different pieces together for different clients.

I really like programming this way because I get to see everything that's going on, and my private data structures are protected from prying eyes :-)

Norman Ramsey
  • 198,648
  • 61
  • 360
  • 533
  • 3
    IMO this answer is much better than the accepted one because it gives an alternative to globals. Passing data around is almost always more clear, even if it increases the number of parameters a little. Thanks for your insight. – Chris Middleton Aug 14 '15 at 20:37
11

First, there's no point in pretending that singletions are somehow better or more acceptable than globals. A singleton is just a global dressed up to look like OOP. With a bunch of other problems thrown in.

And the alternative is, of course to not have global data. Instead of your class accessing some static (global) variable somewhere, pass the data to its constructor. Yes, it means you have to add a few arguments to the constructor, but is that a bad thing? It makes the dependencies for the class explicit. I can test the class simply by providing different objects to it in the constructor, whereas if it relies on global data, those globals have to exist in my test, which is messy.

Similarly, I can refactor easily, because there are no magic dependencies on classes other than what's passed directly to the object.

Thread safety gets easier to manage because you no longer have all your objects communicating with the same global instance. Instead, they can be passed separate instances of the class.

jalf
  • 243,077
  • 51
  • 345
  • 550
  • 5
    Do you want to pass a logging instance to every function, or a user language, or the location of the help file so it can do context sensitive help. – Martin Beckett Dec 13 '08 at 18:30
  • 1
    maybe. It depends. It's an alternative, but it's not the *only* option. But if **every** function needs a user language or the location of a help file, then it sounds like you have bigger problems in your code base to worry about. I personally am (usually) fine with loggers as globals, because they don't influence the program flow. But I don't trust *mutable* global state. – jalf Aug 21 '11 at 14:41
  • "And the alternative is, of course to not have global data". It is common in almost every program to have some kind of global data/state/ single source of truth. – Konrad Oct 02 '19 at 16:21
5

I wouldn't care if singleton or global variables are not recommended. If I feel like that is the most logical way of implementing it then I'll go ahead and use it.

Naveen
  • 74,600
  • 47
  • 176
  • 233
2

That entirely depends upon the problem you are trying to solve. This key bit of information was left out by you. If you're looking for an over-arching solution, there isn't one. There are merely patterns which we apply when applicable.

TheSoftwareJedi
  • 34,421
  • 21
  • 109
  • 151
1

The most common concern I've seen with both globals and singletons is that you risk bad behaviour when using threads. In this case, you should always use execution scope as your base unit. This is one of the strengths of OO programming - you can use object members to hold all relevant data with very little fear of accidental thread mayhem. This stands in contrast to a non-OO-capable programming language, where you'd have to hand data down via parameters.

The other common concern tends to be organizational - it's hard to understand exactly where data comes from in a large system when it can be read/written to at any time. This is, in my experience, more a problem with the developer rather than the code per se. Unless you're working on one of those hundred-million-line megasystems that seem to crop up mainly in programming books as examples of difficult problems, you're going to be able to search your entire codebase for a particular item in a reasonably short period of time. The necessary next step is to regularly audit the codebase to ensure that globals/static variables aren't being assigned to at random. This is anathema to a lot of development approaches, but for systems under a certain size and complexity it's a perfectly workable solution.

Mike Burton
  • 3,010
  • 24
  • 33
0

after using globals and singletons and seeing everything get messed, I came up to this solution.

  1. make every global variable a member of a class. Logically every global variable belongs to application (or system). just create an application class. define global objects as properties. so they are created when first called.

  2. create a singleton for application class, so you can access it globally. This will be the only singleton in your code. well, at the end it is like system.out or system.in objects in java.

note: I know that, this is a very old question, but still popular.

bkilinc
  • 989
  • 2
  • 13
  • 28
  • Can you elaborate on why, if at all, such a singleton is really better than globals? Singletons are often (usually?) just a convoluted way to obfuscate the fact that you're really still using global state. I'm guessing you're implying that one could encapsulate variables in the object with getters/setters, but it's not clear. Even in that case, people tend to argue that there's no real need to enforce its singletonness via all the boilerplate that pattern demands; just don't instantiate it more than once. – underscore_d May 13 '16 at 09:41
0

A common solution to this is to use single-instance classes instead of singleton/global variables.

Your application will be responsible for making sure you have only one instance.

This solution kinda sucks 'cause you can't prevent people from instanciating your class (is not a singleton) so it must be an internal class.

I wouldn't care too much about all the religious wars about the singleton pattern though - If I think it suits my needs i generally use it.

JohnIdol
  • 48,899
  • 61
  • 158
  • 242
0

global variables a re fine in small programs, but when they get bigger you start getting weird side effects when someone makes a change or fixes a bug by going "oh, i'll just set this global and the problem goes away"

EddieD
  • 916
  • 2
  • 9
  • 10