Hello, please follow me in the dilemma I’m facing. In my game I make everything at runtime, reading from external files and then building what is required.
I have a monobehaviour where I store and cache loaded and built assets, they are stored in a private static Dictionary, and I get them out from there from a static function. It all works fine and all, my doubt is if I should drop this system and convert the script to a singleton.
When changing scene I have in place already a system to clear the static dictionary from stuff I don’t need aymore then proceed to add new one if the scene requires it. Got a doubt on this too, clearing a static collection will give me back memory, or once is populated it will keep the same memory amount no matter what I do to it?
adding static to your class variable makes it automatically a singleton, or Omni. Its how you implemented it that makes a difference. Just like when you add abstract to a class.
So basicly I would get back the object from the function by referecinging the script directly, or is better to do like this?
private Dictionary<string, object> _cache = new Dictionary <string, object>();
public object GetCachedObject (string id)
{
blah blah return object;
}
Using the Instance of the script in this case.
What would be the cons of having the dictionary static? Just to add to it, this whole thing is done once at scene load, then enver on the fly while playing.
Static and singleton aren’t the same thing. I’ve also never heard the term Omni.
“better” is sort of a loaded term. I’m sure you’ll get people arguing on either side. If you made it a singleton that didn’t survive scene changes and lazily built its cache then you could theoretically reduce some coupling in your code. As you have it now (assuming based on your description) you need to hook scene loads with some logic to clear the existing cache and repopulate it. That would go away if the singleton was simply destroyed with the unloaded scene (assuming you dumped your cache in OnDestroy). Then you could populate the cache in the new scene the first time something else needed it
public static void GetInstance()
{
if (instance == null)
{
instance = new GameObject("_cache").AddComponent<Cache>();
PopulateCache();
}
}
I’m not saying that is “better” (if your cache takes a long time to populate and causes too much frame latency for instance).
Singleton is a design pattern, class types are used to follow this pattern. There is no other reason to use static other than when your doing singletone. Means you have a single class/variable. Omni means 1 channel or Universal. You can google it.
When you add the static type to a class it can only be one instance of it, how you design your singletone is up to you,
AddComponent is expensive, i would rather use something like this:
public sealed class Singleton
{
private static Singleton instance = null;
private static readonly GameObject ThisGameObject = new GameObject();
Singleton()
{
}
public static Singleton Instance
{
get
{
lock (ThisGameObject )
{
if (instance == null)
{
instance = new Singleton();
}
return instance;
}
}
}
}
I did and nothing came up in a programming context.
Disagree. Static utility classes that are stateless, for one.
True. I misread what you wrote to mean adding static to the classdefinition.
No it isn’t - and you’re doing it once anyway. And if you want your Singleton to also be a MonoBehaviour then the only other way to do it is to manually place it in the scene or make a prefab of it and instantiate. If you don’t then obviously that part can be skipped.
I’ve never heard the “omni” term before either as applied to the singleton pattern, and unless my google-fu is weak this morning, some google searches didn’t turn up anything. Even stackoverflow didn’t turn up anything unless you’re talking about OmniXML.
Anyway, all that’s a bit off topic from what the OP wants to know
Not every word in the English dictionary is related to programming, it was just a way of my speaking… Singleton is a design pattern not a syntax I am pretty sure Omni have been used with eCommerce as concept… (lets not dig ur self out of the topic here)
Actually when i come to think of it, its more than that. (i was more wrong here) Because you can Implement a Interface in a Singleton, some thing you can not with static , ohh well my bad sorry.
I know its off topic, but this is not thread safe. If ThisGameObject were of a type System.Object (or similar) then it would be safe. Lock objects should be completely private, as best practice. However, GameObject references are publicly available to any class via Unity’s Find* methods. Trouble can ensue.
As to the topic at hand:
Prefer singletons over statics, for serialization.
Prefer services over singletons, for testabilty.
Prefer injected references over services, for decoupling.
Each of those preferences comes with increased complexity. Increased complexity should only be considered when the benefits outweigh the overhead.
The obvious answer is if you don’t have any immediate problems, what you have now is fine. Otherwise you can spend way too much time redoing stuff back and forth for no good reason.
A Monobehaviour with statics? That’s odd. If you have static variables, you may as well use a regular class and not need to attach it to any gameObject. Likewise the advantage of Monobehaviours is you can use the Inspector, and easily make several as needed (but if it works now, don’t change it.)