Singleton or static pattern

This pattern works very well for me:

GlobalVariables.cs

public static class GlobalVariables
{
    public static GameController gameController;
}

GameController.cs

using UnityEngine;

public class GameController : MonoBehaviour
{
    void Awake ()
    {
        if (GlobalVariables.gameController == null) GlobalVariables.gameController = this;
    }
}

and I use “GlobalVariables.gameController” whenever I want.I just want to know why I had to use singleton while I can use static class for all global variables?

You don’t have to use Singleton.

Also you don’t necessarily use a Singleton here. I mean… you have a global access point like a Singleton, but no code exists to enforce that a single instance only exists.

Note… the point of a Singleton is to enforce only 1 instance of an object, while maintaining object identity for that object.

A purely static implementation has no object identity.

A static class has static code. It cannot be instantiated, so there can be no use of class variables to hold state.

When we need to have state, Singleton is a design pattern to create static like access to a single object. This gives us the advantages of objects. If you don’t care about class variables, either because you have no state to track or you don’t mind the disadvantages of static state, then you could just use static class methods directly.

So, may I rephrase your question to: What are the disadvantages of static state?

Then … I will say:

  1. Static state requires a dependency on a concrete type. You cannot program to an abstraction, so it will be difficult to change the implementation of your state later.
  2. Static state is hard to mock. It might be harder to run diagnostics of your program and it will certainly be harder to run outside of the main framework (e.g., if you wanted to run unit tests)
1 Like

So why object identity should be important for me? I don’t have access to it and I can;t change it.

I didn’t get what you mean by “State”? would you please show me an example that I can’t use Static and the only choice is singleton?

You can use static, however there are the disadvantages I listed in my last post. Singleton is not your only choice but it is a good alternative because it eliminates the disadvantages I listed without introducing any new ones (besides a little confusion which you are dealing with now).

State is contextual information that is important to keep track of. For instance, say you ask me a question. When you leave and come back later with some follow up questions, would you like me to remember that you had previously asked a question about singletons? If so, I will need to record the information somewhere. That is state.

That’s it! Thank You!, at this point in my code (because it’s so simple) I think I don’t need to use singleton.

By object-identity, I mean the same thing as what eisenpony was saying by “state”.

An object has identity. In that it is unique from other objects even if those objects are the same type as it. This identity is maintained most often through ‘state’. And this state can be referenced… passed around as an object.

Static classes lack this state/identity. You can technically give a static class a state, in that it can have variables/fields that can change, making them stateful. But it lacks uniqueness, since there can’t be another static class of its same type with a different state. This fact that a static class technically can have state, just not the state we mean when we talk about an object’s state, and is why I use the nomenclature “object identity”.
https://en.wikipedia.org/wiki/Identity_(object-oriented_programming)

Well, as beginner to the programming, I really need to understand logic behind the goal to use Singleton, So I think this is the logic pipeline for me:
We have a class that many objects can be instantiated from it > but we need to be only one object > what we can do? we can use static class which is unique > but wait! with static we loose benefits of Object (for example we can not create a State Machine Pattern) > So how we can have both static and object at the same time? > Singleton.
Please correct me if I’m thinking wrong.

Yes, you could.

Yes.

No.
You could also implement a “state machine” using class variables, i.e. static members, but this that would not be a very flexible design. Don’t do that.

The benefit of a singleton in contrast to plain static “state” that the other guys were about to point out (referring to it as having an actual object identity and object-contextual state) is that you can actually treat it like an instance and have the usual OO advantages:

You can pass it around as an instance (which is important in so many cases), you can use inheritence (you could have an abstract singleton base class that you derive from, especially useful in Unity since you need instance checks in Awake and destroy to control the validity of an instance), you can implemenet interfaces and treat it using that specific part of the abstraction and so on…

You cannot do that with a static class. It’ll also be easier to drop the singleton approach and use a different system to control the instance management using various frameworks.

Though, there are still disadvantages with common singletons that can turn your code into a nightmare, especially when you’re working with a highly modular code base and when you need to test the code. In the end, you still need to know a concrete implementation’s class type, which is often not desired.

You’re basically creating an identity that makes the rules for its own species. It’s alot of self-awareness for a type and all its surroundings - imagine that in real world.:eyes:

You can use service locator. It is better than singleton because of maintainability and testability.
You can utilize inheritance and interfaces as well and you don’t need to define static field GetInstance and change your every class to singleton pattern

That’s not a given fact, this can quickly turn out to be the extrem opposite. I had hoped the discussion in your thread would have pointed that out.

If you want only one instance of a class, you should not apply singleton! You can easily force it to instantiate only one without singleton
You use singletons because you need it in many places(global) and you want only one instance of it for example SoundManager,EffectManager,PanelManager,…

Sometimes you realize your globals aren’t really globals. They might temporarily switch (like the scoring stats for a mini-game,) or they might be different for things at the same time (instead of life-bar constants, you really need 3 sets for mooks, heroes and bosses.)

Sometimes it’s better to not worry - you can do the rewrite once you realize how you really need them. But it’s always good to do a little thinking about whether they really are one set of vars everyone shares, always. The unity “singleton” scheme makes it easier to make “everyone uses these; now everyone uses these others” swaps. But it’s a little more complicated to use and runs a little slower than just statics.

The main reason in Unity to not use statics is to take advantage of the Inspector. Suppose cowFacts is your class. If you inherit from MonoBehaviour and slap it on an empty, you can pre-drag textures, audio files, meshes … . You may as well make your globals be non-static class variables (otherwise you have to remember cowFacts.cowCount (name of the class) vs. myCow.cowSkin (myCow is your reference to the gameObject with cowFacts on it. cowSkin is a dragged-in texture.)) And you won’t see the statics in the Inspector, which is a tiny bit more awkward.

As a beginner, I think you’re understanding is pretty good already! Of course, as the others have pointed out, there are a few technical things wrong with what you wrote and a whole lot of other considerations.

Personally, I think the main source of problems with using static is that it precludes programming to abstractions. When you refer to a static class, you are creating a strong dependency to a concrete type. This is basically throwing away every benefit we get from object oriented code and reverting to procedural code. Most other problems people discuss with using static are just symptoms to this root cause.

The primary use case of singleton should be to “ensure there is only one instance of this object”. Comparing it to static is not really correct because static code is not typically object oriented code. OO is a pre-requisite to be talking about design patterns like singleton.