- Home /
Static variables and Design Fundamentals (singleton)
So, I've been pondering this question for quite some time as I am a self taught developer, and outside the scope of scripting inside of Unity, my knowledge is pretty lackluster in terms of software engineering.
I've read my share of books with design principles, and can see why singleton design patterns and the use of static variables and the like are a bad choice in terms of flexibility, debugging code, and being thread safe etc... In direct relation to Unity though, is it all that bad?
Take for example, I'm working on another prototype to showcase, and the UI that I am creating has a lot of instances where that particular UI will only have one instance of itself. In turn, the UI text will be populated by properties of a "Client" object, which in turn will of course not inherit a singleton pattern because of the re-use of said object. So, the script that is attached to a GameObject managing a certain "panel" of UI ( that has several components that aren't duplicated and will not be ) has several static variables that can be edited by accessing the class name and not the cached component name, as it won't ever be instantiated that way.
I can see how things can go awry if I were making use of this class and instantiating in several places, but I'm not. I don't really have the experience to determine if there is a better way of managing these one-off instances of UI, and if using static variables is appropriate in this situation where I'm certain I don't need to re-use the class. Is this a normal practice in this particular situation inside the scope of scripting with Unity, or in general, game development? I don't see the need to create a class and make locally available variables when I'm certain there is only one instance, and one access point for my particular situation ever.
Answer by whydoidoit · Jul 09, 2012 at 06:12 PM
There is no problem in using a singleton pattern when the code you are writing is providing a service to the rest of the application - it appears that is exactly what you are doing and the singleton pattern is a good choice in my opinion. Using lots of static variables as globals is generally not good practice, as it makes things hard to find, but well encapsulated modular functionality should still be easy to debug.
Statics can be used in a thread safe manner by decorating the definition with the [ThreadStatic] attribute. This causes every thread to have its own copy and can also be useful when you don't want to make complex relationships between classes or pass lots of pointlessly difficult to route parameters. This is often a style thing and also depends whether you are working as a part of a team. If you start having to teach half of your objects about another set of objects then it is time to consider statics.
Thanks for the reply $$anonymous$$ike... Would you, in this situation, then deem it okay to use and access the class by accessing the class name itself, such as GUI$$anonymous$$anager.someProperty? Or would something more appropriate such as a singleton manager be better for my use case?
http://www.unifycommunity.com/wiki/index.php?title=A$$anonymous$$anagerClass
The reason I ask is that when creating a class like this that manages single instances of variables, I'm finding that I need to initialize static variables by doing a GameObject.Find in start or the like, and it just seems from my standpoint to be lazy and irresponsible in terms of coding, but I don't have the knowledge or experience to decide if this is so.
For another specific scenario, I'm creating a heavy GUI based application that has several tables that will populate by client objects that get their information from an SQLite database of properties. I make these tables statically available so that children can be added, removed, and accessed on the fly to different parts of the UI. Is this okay? Is there another approach I should be taking?
I usually just have a static Instance (or in my case Current) property that I initialise to the instance of a game object on Awake rather than copying things around (clearing it on OnDestroy if it is still the Current item). That said - I also have classes that will do a find in the static constructor or indeed an instantiation of a game object and the addition of a behaviour to it. It's initialization code so it doesn't really matter if it is slow. I prefer to make sure things aren't fragile though. For instance the static constructor of my login class does a LoadLevelAdditive on creation to ensure that there are some common management components available in every scene.
To your second point - if there are tables that are also utilities to multiple classes then it makes total sense for them to be static.
When I code I try to separate what is framework from what is game. Framework should be able to use statics and game should generally not.
Thanks again $$anonymous$$ike, that clears any uncertainties that I had in my $$anonymous$$d. Being self taught and not having anyone to mentor me in terms of advancing my coding practices is difficult, but generally I like the "throw your self in the fire" approach, it helps me learn better.
To clarify that last point - if I find I want something that appears to be a game element to be static or available generally I usually try to decide a) is this something that is genuinely useful, in which case make it as generic as possible and consider it as a viable solution in multiple instances b) consider that if it's a one off that it had better be damn important, or do it a different way.
Your 'b' point is why I was worried. I've never personally had issues debugging or tracking my code since I'm a sole developer, but I'm getting to the point where I'll be giving my source to clients potentially, and I want to know that I'm doing things right, and make sure they won't be a disaster in the hands of someone else.
The damn important or do it a different way is where I'm co$$anonymous$$g from. I worry about efficiency and doing things THE RIGHT way, or at least a generally acceptable way, or some irresponsible practices will be weaved into my coding, and that's the last thing that I want. I'm in program$$anonymous$$g for the long haul.