Singleton or what?

Singletons are bad, they are too accesible, but what do I do then?

I would like a general solution, but I’ll explan a specific situation: in one of my projects there is “wind”, and it doesn´t make any sense to have two winds, does it? So I use a singleton for the wind, now cannon balls can know the wind direction and deviate accordingly.

But any other object in the game can access that singleton as well! That´s prone to error… I could add a static wind variable in the cannon ball class, I create one wind instance and that´s it. But wait!! Imagine I add anyother class that is also affected by wind, ballons, or birds… Then I couldn´t create another instance, I should look for “the only one”.

In my case that ends up with the deepest cry of anguish, and then I write a singleton…

Or is there anything else I can do to avoid singleton?

You mean shoehorn another solution into the problem that a Singleton was specifically designed to solve? :slight_smile: Just because you think “Singletons are bad”?

Exactly!

To add some coal into the debate I found “InternalsVisibleTo”

Would it be better than a public singleton using an internal singleton?

And to further justify the debate, I have to say that I don´t hate singleton, I like it and I use it but I have to admit that it adds complexity to the code, as some singleton-haters have often said. If my UI classes can see the wind singleton, there must be an error somewhere!

As with every design pattern, singletons have their uses. They should not be used where you don’t need them. But when you need them, by all means use them.

One side-note, especially with singletons, be wary and search for another solution before just wrtiting a singleton.

About the UI classes seeing the wind, that is the added disadvantage of using singletons in unity (in another environment you might have you UI classes in another namespace then your wind… (can unity do that??))
But is it really bad? It is prone to error, but do you want to spend time and write more obfuscated code to fix a problem that is not really a problem?

Why is your UI and wind in the same namespace? Ok, now I’m just being cheeky :slight_smile:

Well yeah I didn´t think of namespaces… I usually use only one for the whole project! that could be a real helper. However that was only an example, singleton will still be accesible to all the classes that share namespace, and probably there will be a few!

I keep using singletongs, I just want to open a debate to listen to other solutions.

Well, that is kind of implied in the definition of singleton

  • Ensure that only one instance of a class is created.
  • Provide a global point of access to the object.

If that is what you need, then that is what you should go for.

My personal solution is to create one singleton (GameManager) which holds instances of some other important manager classes. This is probably not the most elegant way of handling things, but it works for me…

Coding is always a compromise between getting things done and making beautiful code. Sometimes something has to give

Well it sounds better than having every singleton dancing around on their own.

I´m still trying to make “InternalsVisibleTo” to work, because that way I could specify each of the dependancies of the singleton explicitely.

Any other solutions (I am sure there must be a lot!) would be welcome!

I think unless you are developing something you expect to be modded and extended by others, or you expect to have a huge code base with a big team working on it, then singleton is just fine, and the other methods just add a lot of typing and hassle for no benefit at all.

You are right, you are all right, but I don´t want to avoid using a good practice, if there is any, even if it means a little more coding. I want to be enlightned.

I´ve seen posts on stackoverflow recomending to pass the variable, but how do you get the first reference? I think it would be cool if C# allowed friend classes, just like C++.

I came up with an idea on the train (trains are the best for thinking). I think I will create a namespace for all singletons (what about com.myproject.singleton?). Then I will have to explicitely declare that I am using singletons whenever I need them. It´s not perfect but at least it is more explicit. I could also create different namespaces for singletons grouped by functionality but that seems a pain to remember.

Would that not mean that if your player needs to access a singleton and your gui needs to access a singleton they both have access to all singletons? Sounds like you dont need the separate namespace for that.
IMO it would be better to keep different areas of your code in different namespaces and include the nessecary singletons in their respective namespaces.

And wouldn´t a further level of separation compensate for the fact f singleton publicity? Even if I do as you say, I think I would add another namespace to singletons, just make its use explicit.

Generally speaking, code should be grouped by what it does not by what it is. If you have a singleton that manages your UI then it should be in your UI namespace. To me, having a namespace called Some.Thing.Singleton is about on par with having a class called MyUIClass or an interface called ButtonInterface.

That´s true… in the end I guess there ARE good reasons to use singletons, or otherwise no one would have started using them in the first place.

There’s plenty of reasons, but like anything, it has a specific purpose.

Reviving the topic… I’ll state some of the affirmations I don’t agree to.

  1. “If providing a global point of access to the object is what you need, use Singleton.” - I don’t think this is the case, and for the matter of fact I don’t think this is desirable ever. I do think it’s acceptable for a Log class or Sound, but that’s it for me.

  2. “in the end I guess there ARE good reasons to use singletons” - The only good reason for using Singletons is sloppiness and lack of knowledge in Object Oriented Programming. Simple as that.

  3. “Coding is always a compromise between getting things done and making beautiful code” - That’s not true. I recommend you to read this. Even if you don’t think you’ll ever agree with it, it’s still good to acknowledge that:
    Design Stamina Hypothesis
    Technical Debt Quadrant

All the other “advantages” can be reached with good design: single instance, grouping, etc.

You don’t need friendly classes for that. In Dependency Injection you normally have a class where you inject your references in other classes. It’s normally just a bunch of code with no logic or ifs, just a lot of class initialising, passing each of the dependencies through their constructor or setters. Classes that can’t be instantiated from the beginning, which need other parameters or context, are instantiated using Factories, which inject the dependencies on the generated objects.

Software is meant for being changed. Requirements are always changing, the market changes, our product vision changes. When you use Singletons, you inevitably end up putting Business Logic where there shouldn’t be. You create dependency cycles without knowing. You change a bit of functionality and end-up changing another you had no idea (or memory) existed. You rely on states that will never exist. You forget to check states that exists only sometimes. That all mean a lot of time wasted with bugs. Much much more time than using proper dependency injection.

That being said, I come from an iOS background where many people also think that Singletons are the only way to go. And I’ve created some huge projects without only one singleton. It took a bit longer at first to learn but believe me, it paid off. Adding features, fixing bugs, maintaining code I haven’t seen for months, it all gets much much easier.

Unfortunately I’m just starting in Unity3D, so I don’t know how to answer you, but I’m sure it’s possible. It has to. If it’s not, Unity3D team should make a way of doing it.
Another recommended reading is this: Clean Coder Blog

Just realized this was a necro’d thread, but yeah, I was also going to say “Dependency Injection!” If you’re interested in using Dependency Injection in Unity I would highly recommend Zenject:

Unity’s peculiarities, like not being able to use constructors for MonoBehaviours or GameObjects, makes some of the usual ways of using dependency injection in C# impossible, but Zenject does a really good job of bridging the gap and combining the best of depenedency injection with Unity’s component design.

1 Like