Singleton classes really that bad?

There was some recent discussion on here that mostly claimed that singleton classes, assuming they had state, were bad (I'm not quite sure what a stateless singleton would be other than a different naming convention for global functions). I'm unconvinced =)

Stateful singletons still offer one advantage over straight global variables -- they have encapsulation. Granted, it's not any better than having a global object, but it does at least seem a little safer in that you can control access to it, cutting down a lot of the arguments against global variables in general. I'm not sure what nightmare scenarios people are thinking of when they say singletons can change unpredictably.

Can someone clarify?

I'm thinking of a class having C++ code something like this. For the sake of argument we'll say this is a design situation where we know we'll only need one of this class.

class DataList
{
public:
    static void AddToList(ctl_node& node);
    static void Display();
    static ListIter Begin();
    static ListIter End();
protected:
    DataList();
    ~DataList();
    static DataList& Instance();
    
    ListType nodeList;
};

DataList& DataList::Instance()
{
    static DataList theList;
    return theList;
}

void DataList::AddToList(ctl_node& node)
{
    DataList& theList = Instance();
    
    theList.nodeList.push_back(&node);
}

That's enough to see how the functions would get a reference to the one instance.

Thoughts?

Comment viewing options

Select your preferred way to display the comments and click "Save settings" to activate your changes.

singletons can't be replacec by interfaces

You definitely give up a lot of freedom with a singleton, since you can't replace it with an interface. Think about testing for example. No way to fake a singleton with a mock.

Cheers,
Ralf.

Hmm....

Hmm... in the C++ example yes.

But is that a fault of singletons themselves, or the language for not giving enough support for singletons? For example, a language with builtin support for singletons could let you attribute a name to a singleton class so that calling methods on it would be syntaxually the same as calling a normal class.

Scala

Scala obtains a syntactic notion of singleton objects that are indeed classes capable to instantiate exactly one object. Scala also prevents static methods in favour for methods of singleton objects.

Kay

Do programmers hate scala for it?

Do scala programmers avoid stateful singletons still?

You shouldn't...

...need to do that. A singleton should be, by definition, a class of only one specimen. One criticism levelled against singletons is that what often seems a quite clear-cut design constraint ("it makes no sense to have more than a printer spooler") often evolves to be invalidated, but the pattern has fixed the architecture to make it difficult or expensive to change. The "correct" pattern to apply in these cases is Factory, say the ones in the know.

The point is that a complex program is often modelled as a group of interdependent services. Factory allows for both discovery and instance management of the service providers; however, the implementation is heavy-weight in terms of boilerplate needed, and best used for architectures (i.e. class libraries that will pay themselves off, or heavily refactored, mature code that has already paid itself off). Dependency-injection frameworks exist, and are fine and dandy, but their use does create a new, architectural dependence in your code. This is why I think that Singletons are OK while coding in the small, provided you are aware of the trade-offs.

If you would like an unqualified endorsement for the use of Singletons, I would defend the pattern for modelling the null object adhering to an interface, for instance. I find that null objects have a rightful place in the hierachy above and beyond mocking or scaffolding, as the minimal expression of a concrete implementation of an interface when different implementations offer varied degrees of behavior or sophistication: a Factory then might choose to return a Null when it can't satisfy a request, instead of signalling an exception (which can be more inconvenient to deal with than to work with a inoperative but otherwise valid exemplar of the interface).

First a question...

What is wrong with goto? When Dijkstra wrote the seminal work on structured programming, the code of the day was filled with gotos. Whats wrong with gotos really? All control structures get converted into a jump instructions of one form or another eventually. There is, in fact nothing inherently wrong with gotos, just as there is nothing inherently wrong with global variables. In fact, there are many cases where it is difficult to get by without a goto (as it is sometimes difficult to get by without the use of global variables). The answer, of course, was that gotos (and global variables for that matter) make it difficult to reason about your code. Consider this ad hoc code segment (written in no particular language):

    x = 10;
    // some code that doesn't modify x
label:
    // more code that doesn't modify x
    print x;
What gets printed? The fact is, with possible gotos in the code somewhere, that seemingly simple question is actually very difficult to answer. A key property of a well designed system is lost when the programmer becomes promiscuous with the goto statement. This property is, locality, as identified by Richard P. Gabriel in Patterns of Software. According to Gabriel, locality is that property that allows a programmer to understand part of a program by only looking at a small portion of it. In the above example, we may not have complete knowledge of the small portion of code shown (assuming we knew what code was in the "code that doesn't modify x" portions) without looking at a much larger piece of code. We may even need to look at the complete program. This is not good. Hence, Dijkstra's paper on structured programming. Loops, conditional statements, and other control structures, along with avoidance of the goto statement, allow the programmer to reason about his/her code with greater ease.

Why should global variables be avoided? For the exact same reason the goto statement should be avoided. Improper use of global variables can make reasoning about code more difficult. Code encumbered with globals has become a pile of spaghetti: more likely than not, you wont be able to reason about one piece without picking apart other pieces.

Why do some people consider side effects something that should be avoided—even to the point of banishing them from a language all together? One reason is that side effects tend to induce the same problems that global variables and gotos induce. In fact, many of the problems with gotos and global variables end up boiling down to a side effect issue!

So, what does this have to do with singletons? Well, the problem with singletons (and, in my opinion, much of the OOP I see) is a reduced ability to reason about and test code. In the example class you gave, there are all sorts of problems when using the data stored in the list, because that data could be modified from practically anywhere else in the code. Someone maintaining a larger program with the DataList would have difficulty trying to figure out why the code broke, not realizing that random functions might be modifying the list, even though it wasn't obvious they would have such an effect. For example a programmer might get into the following situation:

someType someClass::MethodA(DataList list)
{
    //...
    list.someListOp(foo); // Everything's fine.
    anotherObj.MethodB(bar);
    list.anotherListOp(baz);
    // Unexpected results here...
    //...
}
In this example, it isn't clear that anotherObj.MethodB(bar) could change the value of list, but it is very possible (and, in fact, highly probable as the code size increases) that such a thing would occur.

If you think about it, the functional style is the easiest to reason about, and the easiest to test, since every procedure (function, method, whatever) is an independent unit whose value remains constant with respect to constant inputs.

I dunno

As I mentioned in my original post though, at least a singleton has encapsulation. A global primitive (int) can be altered less predictably than a class for which you control all of the accessor functions.

In the above example, I could prevent arbitrary editing by making Begin and End returns const iterators for example, but provide a Find method taking several parameters for a node in the list to match, that returned a non-const iterator. This way clients could alter the list if they found something inparticular they needed, but couldn't alter it arbitrarily by iterating over it.

You also mention that you can't know that anotherObj.MethodB(bar) or any other arbitrary method/function won't alter the singleton. Not having a DataList singleton/global doesn't necessarily narrow it down a lot. It doesn't even narrow it down to other objects that contain references to the DataList. It only narrows it down to all objects that could potentially contain a reference to the DataList. I'm not sure if that scales such that as the code gets larger the narrowing becomes more useful or less effective.

only one solution

There is only one way to ensure that anotherObj.MethodB(bar) does not modify the DataList list -- Have the compiler disallow it.

One way to do that is to allow a variable to only be assigned once. This is what strict functional languages do.

A little off topic:

The concept of "code locality" sounds interesting. I found the book you mentioned on amazon, is it worth reading?

If you are referring to Patterns of Software...

you can always read it first and find out. http://www.dreamsongs.com/. If you are just worried about the time, then it depends: it's more philosophical than technical. In fact, it is not very technical at all.

Patterns of Software

Yes, as Derek Elkins points out, Patterns of Software isn't a technical book, but rather more of a collection of philosophical essays on software and software design (along with stories). And, yes, you can read the book online for free. (That’s what I did.)

I just mentioned locality, because I identified that property (or lack thereof) in software I've seen or have had to maintain. The essay in which the concept occurs is entitled "Reuse Versus Compression" that discusses reuse and object oriented programming. I had read this essay shortly after watching the SICP lectures, so the oftentimes elegant programs from SICP were impressed in my memory along with the struggles of having to figure out what was going on in the complex hierarchy of code at work. Not that there's anything wrong with the OO way, it has its benefits and its downsides, but I do believe that the Object Oriented paradigm would benefit greatly from ideas borrowed from the functional paradigm. More is discussed in the thread mentioned in the original post. Note I don't advocate getting rid of side effects or mutable private variables all together, but I do advocate ridding ourselves of unnecessarily using them. That is, unless it is very cumbersome or unwieldy to do without mutable private variables or side effects, you should write your classes in the functional style. (This rule becomes more important to follow as the class size increases).

Locality vs. Localization

It might be worth comparing RPG's locality with the notion of localization from Ross, D.T., Goodenough, J.B., and Irvine, C.A., Software engineering: Process, principles, and goals. COMPUTER 8, 5 (May 1975): 17-27, a seminal paper in the history of SE which influenced the design of programming languages.

This paper also seems interesting (but it is hidden inside the ACM DL...)

Ada, yet again

Setting aside the general question, one should note that singletons shouldn't require so much work to make sure only a single instance exists. This clearly reduces readability and can cause bugs.

In Ada, you usually create singletons by building an Abstract Data Object (ADO) - which is essentially a package that has state. Since packages have only one instance, regardless of home many times they are referenced, you get the abstraction of a single object without having to resort to any tricks. Abstract Data Types (ADTs) require that a type be exported from the package.

The discussion regarding ADTs vs. ADOs in the Ada Style Guide is worth reading.

"Patterns of Software" book

I read this when it came out. It's quite a mixed bag - part autobiography, part industry history, software, persian rugs, the lot. Eclectic but entertaining.

Just don't expect a "pure" software book.

Assuming too much

Before I get to my main comments: justify using this class as a singleton, over creating it in main(), and passing it to the functions/classes that need it. Most of your classes will not need access to this list, so why would you make it available. One point of OO programing is to hide data that you don't need. Even structured programing promotes this idea somewhat - why use a global variable when a local variable passed to other functions will work? Please give me an example of a class that will work as a singleton, but will not work as passed data.

That said, you are assuming too much. Today you only need one of that class. Tomorrow you need 10. Your singleton is needlessly inflexible in the face of changing requirements.

When you must have a singleton, go ahead and use them. However most instances of singletons that I have seen in the real world are not needed, and worse, some requirement changes (or was no understood to begin with), the singleton caused problems. Do not reach for a singleton if you have other options.

Your class is not thread safe! What will happen when someone decides to make your program multithreaded? Are you even sure your program is not multithreaded? Now granted you can add locking to one place when you find your program is multithreaded, and this will save some time. However is it really your intent when (and remember the requirements changed, so you cannot state anything) you go to multithreading to have one list? Maybe each thread operates on a different list. Maybe you have 2 threads per list, and 4 threads.

We are reaching physical limits as far as CPU speed. If you need your program to run faster your only alternative is some form of threading. (Assuming good algorithms)

Example: we had a PHP (ick) singleton class to wrap a sqlite database. When php initialized it loaded this class and created the database handle. Then the web server forked. Now, Sqlite has great thread locking, but it does not work for this case and we were getting random database corruption. There was no point in having the database in a singleton, but someone thought the premature optimization would save us some CPU cycles (even though there were plenty to burn). In this case, the singleton fell down because it is not thread safe, and the program turns out to multithreaded enough to break it, even though by most definitions it is not multithreaded.

P.S. Multithreaded programming is hard. Avoid it if you can. However try to design your programs so that someone else can make it multithreaded latter.

Passed Data

A shared (external) resource would be one typical usage for a singleton. Another might be configuration settings, where you don't want to pass the configuration around as parameters.

But why do you need classes with only one possible instance?

Any shared external resource that you can think of; might have more than one instance. Likewise with configuration settings--if you have a global "config settings" object; it is entirely conceiveable that you may need different ones for different parts of the code.

The main use for singletons that I see, is to provide (cooperative) mutual exclusion for system resouces on systems which don't provide their own locking. If I can open a logfile with exclusive access; I don't need my Logger class to be a singleton--trying to attach two instances of Logger to the same logfile would fail at the OS level. If, on the other hand, anyone can concurrently open the logfile that I'm writing to for writing; a singleton Logger class is of limited use--it may protect other instances of Logger from attaching to the logfile; but it doesn't prevent someone from attaching to it with other means.

Nesting

The configuration settings example seems like it needs Scala's nested classes. I don't know Scala well, so this may not be valid code:

class Configuration {
  var foo = 0;
  var bar = 5;
}

class App {
  var config = new Configuration;
  class A {
    def get_foo =
      config.foo;
  }
  class B {
    def set_foo(new_foo: int) =
      config.foo = new_foo;
  }
}

No passing around is required, but some singleton problems are avoided because many instances of App can exist. I think it's also possible to extend App and override a class, which allows an entire program to be extended as easily as any other class.

I know I've wanted this ability before. Does anyone know of other languages that support this kind of nesting?

I would think that most objec

I would think that most object/functional hybrid languages (like Scala) would have this, but I wouldn't swear on it.

quite useless

Obviously there's no compelling use case for a singleton, because you picked the single most useless example imaginable: "DataList". What is this? "Data" doesn't mean anything, it's an even more empty phrase than "Object" or "Thingayamajig". "List" is almost as useless, it just denotes a container. So what, you have a global container of everything? A garbage dump is the most compelling reason to spend mental energy on singletons?

If so, there's not even a need to tell you how singletons violate the Demeter principle, lead to rigid, hardly maintainable and inflexible programs and almost always seem appropriate only because of oversimplified and thus wrong assumptions. (And on a side note, this is the stuff I expect on wiki, not on LTU.)

Hey!

And on a side note, this is the stuff I expect on wiki, not on LTU

As a proud Wikizen, them's fightin' words! :)

Speaking of Wiki (I assume you mean c2)...

... wiki isn't entirely in love with the singleton:

SingletonsAreEvil summarizes and discusses many arguments against singletons. InstanceManagerPattern is a page (written by yours truly) on an alternate "pattern"--one I've discussed here on LTU.

I stated in my original post

I stated in my original post that we can just assume it's something that we know we only need 1 of. I figured if I used a more specific example someone would start arguing the specifics of it rather than singletons themselves, looks like it backfired.

You miss the point - good examples are rare

You are missing the point. There are times to use a singleton, but they are very rare. In most cases when someone proposes a singleton they are just too lazy to write the code right, not in a case where only a singleton will work.

So when we criticize your example it is because you have not thought out the need enough to propose a good example. A singleton should be your last restort as a solution to any problem. In a well designed program you will need few if any.

Because the singleton is easy too many programmers reach for it as the solution of first restort when there is no clear need for more than instance. Even when it wouldn't matter if the class did exist more than once. Thus I have developed a knee jerk reaction to call all singletons bad until a given instance proves otherwise. Turns out most (not all) singletons are not justified and the code should be written differently.

Type systems

What about the type system? There's only one of those and I have global access to it. Can we consider it a singleton or is there something that prevents it from being so? If it is a singleton, should it be? What are implications of having to pass the type system to each method?

Does your type system have st

Does your type system have state? I don't think anyone is realy complaining about global constants.

Dynamic Languages, Java

Dynamic languages, which permit the creation of new datatypes at runtime, have state (though possibly monotonic). Some dynamic languages (CLOS, for one) even allow types to be redefined (or allow different types to be bound to the same name at different points in the program).

Java, through use of class loaders, allows different "type systems" to be in use in different parts of the code.

Of course, types themselves frequently have value semantics; the part of the type system that is mutable is the binding of names to types.

Seems like an iffy comparison

In most languages you only get one function registry (albeit possibly with multiple namespaces), but I think that's sort of beyond the scope of the debate, isn't it? Isn't the typesystem implictly part of the environment that is passed down, from functon call to function call anyway?

Yes. Idioms become part of the language

As you may recall in Peter Norvig's presentation Design Patterns in Dynamic Programming, he suggests that design patterns that become so common become built into languages. e.g. subroutines.

I'm suggesting there are uses for singletons, but we've probably identified most of them and built them into languages already. In fact, as Li Svilling pointed out, most languages don't allow mutable type systems anyway. So, even as idioms built into the language, mutable singletons are frowned upon.

Singleton = module?

Singleton = module?

Module in what langauge?

If you are talking about VB, then a module is almost a Singleton.

The one thing you can do with a singleton that you cannot do with a module is pass it to a method.

Say you had two classes, each representing a diffent way to do the same thing. For whatever reason, you make them both singletons.

You could make both implement the same interface, and thus would be able to switch them out easily. With modules, which cannot implement interfaces, that is not an option.

Note that I have yet to write a singleton that shouldn't have been coded as a module. If I find the need to pass it to a function, then I soon find a reason to have more than one.

Passing a singleton?

Isn't the ability to pass a singleton to a function irrelevant? The function can access the singleton either way.

You're assuming the singleton

You're assuming the singleton's a global. It might make more sense to explicitly construct it at some point and pass it around, depending on the application.

Singletons *are* global.

By the definition that most people seem to use, singletons are always global.

That's because most people ca

That's because most people can never see another way to use them

Interesting.

It would seem to me alternative 1 may be worse than global variables. A programmer constructing a singleton may expect the singleton to be fresh (after all, he/she is constructing it). The problem here is that the programmer may not get a fresh singleton object back. In fact, the programmer has no way of knowing if the singleton is fresh or not without looking through the process the program creates for a previous construction of the singleton object. Now, if our singleton object has no mutable state, this isn't so bad: the singleton is merely a global constant. However, if the singleton has mutable state, it's a global variable that gives the illusion of not being a global variable.

I'm assuming alternative 3 is referring to a run time failure, but I don't see any reason why the compiler couldn't check for multiple constructions of a singleton object. Indeed, after my above thoughts, I'm convinced a compiler error is the best solution to the problem (outside of banning them all together): the compiler just won't let you construct more than one.

Alternative 1 might have one

Alternative 1 might have one advantage over globals: you get tighter scope control if the singleton class doesn't have global visibility. In particular, it might be possible to cast it to a (non-singleton?) parent class that lacks the creation part of the interface and pass the resulting value around...

Passing a singleton?

Usually.

But what if you had two singletons and you wanted the function to work on either.

Interface ITest
Singeton Class A Implements ITest
Singeton Class B Implements ITest

Function X (ITest)

Note, I have never seen this actually used in the real world.

Singleton means two things...

The Singleton pattern does two things: (1) enforces that a class can only be instantiated once, and (2) makes that instance globally accessable.

There's nothing wrong with #1, but #2 causes no end of problems if the object has stateful behaviour. If the object is stateless, is just a value, then the Singleton patter is equivalent to a constant definition. If the object is stateful it is equivalent to a global variable and so creates hidden dependencies between otherwise decoupled parts of the system -- a maintenance nightmare.

Anyway, #1 is a complicated way of making sure a class is only instantiated once. It is much easier to just only instantiate it once at the start of the program and pass a reference to an abstract interface to client objects.

Yes

Yes, (Stateful) Singleton classes really are that bad.

I find the Singleton pattern to be really dishonest; nobody really uses Singletons to enforce singularity, but rather to provide convenient accessability. A Singleton is an "OO global" so it's convenient because you have access to it from anywhere within your system. If we were being honest it would be called a "Locator", "Accessor", or even "Global"! I've asked around and nodbody could think of a legitimate need for Singletons.

I made some comments on this in a previous discussion on globals.

I've compiled a list of alternatives to globals. I would appreciate it if LtU readers have any suggestions for additions or corrections.

Every program needs at least one global variable.

Every program needs at least one global variable...otherwise the app's context would have to be passed from one function to the other as a parameter.

No Global Required (or Desired)

No, you don't want or need any global variables. One global variable that you access all of the others from is just as bad as lots of globals.

There are two approaches:

1. Make your components Context-Aware: have methods (or equivalent) like get/setContext() where you provide a components Context when it is installed/created.

2. Make your components Context-Oriented: have the Context passed from function to function as you say. Just as in Object-Orientation or Continuation Passing Style where you pass around an extra parameter to all function calls, you pass around the Context or Environment. Come to think of it, even Procedure Oriented programming adds an extra parameter in the form of the return address.

Being Context-Orientated is generally more useful than being Context-Aware because it allows your code to be re-entrant. When doing web programming for example you would pass things like the current user's credentials and the current request and response objects down through the Context. With real GUI programming it is often sufficient just to instantiate a component with a single Context.

User data isn't global

Passing around a single context object to every other class is no different than having a globally-accessible singleton. Other than a lot of wasted cycles, it has exactly the same net effect.

But your example doesn't really address that issue. You are talking about a single user's credentials, something that would never be placed in a singleton.

A singleton would be used for data shared by all users. Examples...

  • The number of users currently online.

  • The connection string for the database.
  • A cache of data (i.e. web pages) that are non-user aware. For example, a common menu that is generated from database info and rarely changes.

Desktop GUI Applications?

By passing around a Context object you have the option of only having a single Context if that's all you need but then in the future should you need to change your dependencies you can do so without breaking any of your ContextAware code.

For most desktop GUI applications there is indeed only a single user. If you think Singletons are reasonable then it would be perfectly reasonable to store the current user 's information in a Singleton. And here's the point: suppose in the future someone comes along and says that you need to create a new web-based user interface. Now you have to deal with multiple users at the same time but all of your code assumes a Singleton user and needs to be extensively modified to run in the new environment.

In the above example you may have originally had the user information in the top-level Context. Once you move your code to a multi-user web-based environment you can just remove your user from the top-level and put it in a per user session sub-Context. The Context should have some sort of method like createSubContext() which creates a new Context which inherits bindings from its parent Context.

Abstracted Layers

Easy answer, move the user info from the singleton to the session. The session, being global only for that user.

Real Answer
First of all, porting a desktop application to the web is always non-trival. I have seen examples that use the same UI for both, and they have never been satisfactory for either environment. There are just too many issues involving work-flow and state to account for. So I should expect a major rewrite.

Now, if I wrote my layers correctly then I can save myself a lot of time.

First the data layer. This doesn't have any globals at all. In fact, my my data layer is entierly context free. It doesn't care who the user is or what environment it is running on, though specific functions may ask for a username for logging database changes.

Then there is the UI layer. All user data is stored here. Maybe in a global, maybe in a session. Perhaps I get it from the Windows login. It doesn't matter, since the info is passed on to the data layer in a as-needed basis. This also has a global database connection passed to the data layer.

Requires Changing/Forking Code

Yes, you can change your code to use the session rather than the global namespace, but this is exactly the sort of thing that you should want to avoid.

The point of obtaining all dependencies from a Context is to avoid this type of unnecessary coupling. All that context-aware code should care about is that the services that it depends on are provided, not how they are provided. They could be global, per-session, per-connection, per-transaction, or per-screen. They could be singletons, pooled or per-thread. They could be instantiated lazily or on startup. Whenever you change any of these characteristics of service you shouldn't have to go and modify all of the code that uses it. You may not even be able to modify all of the code that uses it if you've made it available as a library for use by others.

In the example that I gave, with both the Web and GUI user-interfaces, even though you would need to rewrite the GUI, you would still like to share all of the business logic and foreign interface code between the two versions. You wouldn't want to have to maintain two versions of essentially the same code just because one uses a session and the other uses singletons.

Advanced data layers often need to be aware of the principal for such things as: logging, auditing, authentication, validation, and multiple service provider (MSP) support.

There's -nothing- wrong with the otherwise

... and it's not true to boot.

There are programming languages that explicitly work this way for a reason, e.g. E* and Timber. It's not true because you can use lexical nesting to avoid passing around much of the context. Again, see e.g. E or Timber.

If you mean at the implementation level, then while it's probably still not true, for most cases there are already globals at the hardware level (heck, you could consider the hardware itself a global). But this doesn't strike me as particularly relevant (Haskell doesn't translate to pure code for an analogous example.)

* Specifically see 2 in the section Six Perspectives of http://www.erights.org/elib/capability/ode/overview.html

Trivially Falsifiable...

Achilleas Margaritis: Every program needs at least one global variable...otherwise the app's context would have to be passed from one function to the other as a parameter.

This is obviously false: consider a Haskell program that has no mutable state at all, likewise a Concurrent Clean program, or an E program that can have mutable state but can have no globals. The "context passed as a parameter" is effectively what you get, e.g. from the use of monads. It's just implicit rather than explicit. See Oleg's A Serially-Numbering Monad for an excellent example.

One of the more unfortunate consequences of the popularity of the imperative paradigm is that it's quite literally led people to believe that it is inevitable. Note that I'm including the object-oriented variant of the imperative paradigm in this critique.

How would you write this without using a global?

1. I am using a multi-threaded web application.
2. I want to know how many users are currently logged in. This information should be available to all users on all pages.
3. My web server understands user sessions and triggers an event whenever a session is created or destroyed.

Currently I have 3 global functions backed by a global variable.

Public Module Globals
  Private UserCount as Integer
  Public Sub AddUser()
    SyncLock GetType(Globals)
      UserCount +=1
    End SyncLock
  End Sub
  Public Sub RemoveUser()
    SyncLock GetType(Globals)
      UserCount -=1
    End SyncLock
  End Sub
  Public Function GetUserCount
    Return UserCount
  End Function
End Module

Notes:
"Module" creates what is effectively a singleton is Visual Basic.
"SyncLock" ensures no two threads modify the class at the same time.
In a non-trival example, I would store more info like the user's name.

Just pass the counter object to each thread

You can do this simply by just passing the counter object to each session rather than referencing it via a global variable. E.g., in Java it would look something like:

// inside application initialisation
Counter counter = new Counter();
for (int i 0; i < NUM_THREADS; ++i) {
    thread[i] = new MyThread(counter);
}

Each thread can then use the counter object, or pass it on to other objects (e.g. a Session object, or whatever). You could then, in principle, pass different counter objects to different threads/sessions. For instance, if you wanted to count the number of users separately for each section of your site, rather than for the whole site.

Not possible, unless I want to write my own web server

1. I never create threads. Thread management is the responsibility of the web server and associated framework.

2. I never create sessions. Again, session management is the responsibility of the web server and associated framework.

3. The counter object is global to the thread. And since all threads share the same counter object, it is global across the application. You haven't eliminated the global, you just made it harder to recognize as such.

"You could then, in principle, pass different counter objects to different threads/sessions. For instance, if you wanted to count the number of users separately for each section of your site, rather than for the whole site."

If I did that at a thread level, then I would bind a thread to a particular section of the site. That would be a bad thing.

Besides, if I wanted to do that I could alter the global method so that it would accept the section of the site.

Jonathan

ServletContext

With Java Servlets you have the ServletContext class which is shared between different Servlets belonging to the same "web application". You can have multiple independed ServletContexts per Servlet container. You could use the get/setAttribute() methods of this class to access shared resources like your Counter object.

I don't know about the specif

I don't know about the specifics of your setup, and which components have responsibility for creating what. The example using threads was just meant to be illustrative of the general point, not a recommendation for actual implementation. The point is that you can avoid a global variable by making the state an explicit parameter. Of course, if your web application doesn't allow you to parameterise your applications (something which is surely a basic requirement) then you may have trouble removing global variables. That's not an argument for global variables though.

The counter object is global to the thread. And since all threads share the same counter object, it is global across the application. You haven't eliminated the global, you just made it harder to recognize as such.

Well, your question explicitly asked for some globally shared state (a global counter of the number of active sessions) so it is hardly surprising that there still exists some globally shared state. The point is that this state is now an explicit parameter rather than a hard-coded reference. We can configure the behaviour without having to change the source code (e.g. to make the state more localised).

If I did that at a thread level, then I would bind a thread to a particular section of the site. That would be a bad thing.

Then don't do that.

Besides, if I wanted to do that I could alter the global method so that it would accept the section of the site.

Well, you can always rewrite the code to do whatever you want. The idea is to avoid having to do so.

Implementation is important.

The example using threads was just meant to be illustrative of the general point, not a recommendation for actual implementation.

Normally I use ASP or ASP.Net. But if there is a way to do this in another web server, I wouldn't mind seeing it.

For the purpose of this discussion, I think an actual implementation is in order. We have to be careful about theory, because its too easy to have ideas that work for small programs but utterly fail in non-trival projects.

Well, your question explicitly asked for some globally shared state (a global counter of the number of active sessions) so it is hardly surprising that there still exists some globally shared state.

My point exactly.

So the question should be not "are globals are bad?" but rather "what is the best way to expose globals?".

We can configure the behaviour without having to change the source code (e.g. to make the state more localised).

I don't believe that.

I don't see how changing the behaviour that much could be done without affecting source code. I realize that languages let you alter how a program behaves via XML files. But in that case, I would argue that the XML is part of the source code, even if it is never compiled.

Global variables vs globally shared state

So the question should be not "are globals are bad?" but rather "what is the best way to expose globals?"

There is a difference between globally shared state and global variables as a means of exposing that state. With a global variable, all code uses the same name to reference the shared state. This clearly introduces a dependency between all code that references the global — if you decide later that you want more than one counter, then you have to rewrite your source code. If instead you pass that shared state as a parameter to each component that uses it, then they each have their own local name for referring to that state. That means that you can, in principle, replace the reference for one component without impacting any of the other components.

Me: We can configure the behaviour without having to change the source code (e.g. to make the state more localised).
You: I don't believe that. I don't see how changing the behaviour that much could be done without affecting source code. I realize that languages let you alter how a program behaves via XML files. But in that case, I would argue that the XML is part of the source code, even if it is never compiled.

This has nothing to do with XML, it's about plain and simple parameterisation; something every programmer does every day! For instance, creating section-local rather than global counters would involving changing (in your application initialisation) something like this:

// Global version
Counter c = new Counter();
for (int i = 0; i < NUM_SECTIONS; ++i) {
    sections[i] = new Section(c, ...);
}

into something like this:

// Per-section counters
for (int i = 0; i < NUM_SECTIONS; ++i) {
    Counter c = new Counter();
    sections[i] = new Section(c, ...);
}

Yes, you've changed the code, but you've only had to change the bit of the code you wanted to change: you didn't have to change any code in the Section class, as all its references to external state were explicit parameters rather than hard-coded global variable (or Singleton) names.