Search Unity

  1. Welcome to the Unity Forums! Please take the time to read our Code of Conduct to familiarize yourself with the forum rules and how to post constructively.
  2. We have updated the language to the Editor Terms based on feedback from our employees and community. Learn more.
    Dismiss Notice
  3. Join us on November 16th, 2023, between 1 pm and 9 pm CET for Ask the Experts Online on Discord and on Unity Discussions.
    Dismiss Notice

why are people afraid to program Static and singletons?

Discussion in 'Scripting' started by sdgd, Dec 25, 2013.

  1. sdgd

    sdgd

    Joined:
    Jan 15, 2013
    Posts:
    81
    I was just reading of singletons, ... and the idea to me seemed magnificent :)

    well the Q goes

    why are people afraid to use Static and singletons?

    as I'm trying to use as many static as possible but thing is I can't manage to have more than 2% of static stuff as I mostly need more than just 1 of that same variable.

    but there are occasions when I need just 1 and I use just 1.

    I've been seeing many many many times don't use static, ..... ..... ..... are there any other programming stuff that people are afraid of?

    thanks for answers in advance.
     
  2. gfoot

    gfoot

    Joined:
    Jan 5, 2011
    Posts:
    550
    You can use what you like in your own code and there's no need to be afraid, but use of statics is often a sign off poorly architected code. For small one man projects that might not cause a significant enough problem to be worth learning to do better.

    The main problem with statics is that they couple systems together which reduces reusability, hampers iteration, and make testing awkward.
     
  3. LightStriker

    LightStriker

    Joined:
    Aug 3, 2013
    Posts:
    2,716
    I would disagree with just about every point you made.

    They are a sign of poor design only if you overuse them, or use them when it should not be. Like anything, it's in excess that they become problematic.
    It's like saying the "sealed" keyword is bad because you cannot derive from that class, and that's the whole point! Using "sealed" or "static" may very well mean that you know exactly what you need and you planned ahead enough to know it is what must be used.

    "const" also behave in a way similar to a readonly "static", but people complain less about it.

    Unity has far more bigger design issues than what is static or not. Such as the excessive use of MonoBehaviour and how most coder using Unity tends to lack polymorphism in their structure.

    Static is when you know that an item MUST only exist once and that everybody, everywhere, should use that.

    Singleton is like static, but has the advantage of not assigning memory upfront, but only when you need it.
     
  4. gfoot

    gfoot

    Joined:
    Jan 5, 2011
    Posts:
    550
    As I said - you've coupled all your code together, and now your classes can't easily be reused, you can't iterate on your design, and unit testing is almost impossible.

    I'm not such a crusader on this issue, and I do use static member variables from time to time, but I'm pretty sure that in most of these cases it's a sign that I haven't architected my code as well as I could - maybe there were time constraints, or I lacked foresight, or I was just lazy. I also know for sure that I have refactored such code to remove the staticness on many occasions, when my requirements have changed and I've found myself needing two instances for whatever reason. (Resharper is great for this.)

    'const' has totally different usage to 'static' - the compile-time immutability makes all the difference. By a similar token though, you should only use 'const' for something that is a fundamental property of the algorithm, not something that is a user-defined attribute, even if it is immutable at runtime. This is fairly rare, but for example mathematical constants fall into that category.
     
  5. sdgd

    sdgd

    Joined:
    Jan 15, 2013
    Posts:
    81
    what do you mean overuse static?

    like having 30 GameObjects in game that needs ONLY and ONLY 1?

    I heard you must avoid static by any means nessesary, ... well that's no problem you can write a program with no statics but you'll either need to use events and delegates or arrays/lists or saving the data to HDD before loading new scene, ...

    well I disagree for static that only 1 item exist, ...

    I used winner for static and when there were 50 solutions floors the 50 one was a winner title but there was more than 10000 of static winner so actually 1 variable for 10000 items, ....

    I could say more on Singletons but I haven't griped enough on it yet.

    hmmm, ... ok never heard for sealed I did look it up, but couldn't find much what sealed is and how it behaves, ... can it be said more on that?
    is there anything else people are so afraid of?

    but still why are people so afraid of using this?
    I know why is not recommended
    I know when I should never use static, ... but Q still stays same
     
  6. GarthSmith

    GarthSmith

    Joined:
    Apr 26, 2012
    Posts:
    1,240
    I view use of static and singletons similar to having global variables.

    When I first picked up programming, it seemed easiest to just have global variables everywhere and to make everything public. That way if I needed any kind of information it was accessible to me.

    So, as more experienced programmers, why don't we use public static variables for everything? Why do we have private variables and not just make everything public? As I'm sure you all know, having a hundred or thousands of global variables very quickly becomes a mess. Code turns into chaos. Large projects become unmanageable.

    It is the same with static variables and singletons. Singletons should be used to make code cleaner. I think the dark side of singletons is that there's a pull to turn everything into a singleton so any kind of data is available everywhere at any time. Which brings us back to the problem of making everything a global variable.

    tl;dr: Static and singletons are fine. Just don't overuse them.

    EDIT: Static, public, global, singletons are all different things. My point is to keep decoupled and encapsulated code in mind.
     
    Last edited: Dec 26, 2013
    ThomasTrenkwalder likes this.
  7. sdgd

    sdgd

    Joined:
    Jan 15, 2013
    Posts:
    81
    OK I'd say you don't have a slightest idea what static is, ...

    @Garth Smith

    you don't set it Global variable by giving it static.

    you set it global by giving it a public in front.

    if it's a public it can be accessed from anywhere.

    and I mean ANYWHERE!!!! and no static.

    BUT if you say so that static is global variable explain me WHY THE HELL I CAN'T ACCESS:
    Code (csharp):
    1.  
    2. private static bool whatever = false; // from anywhere ?
    3.  
    Everything you said for me is a misuse of static variables
    Thoughtfully I'd never want to have you as a programmer in my company.

    static is a misuse for me when you use it because you accessed it easterly.
    EVEN if you need only 1 instance of it for me it's a misuse because once you'll need 2 you won't understand what's wrong.

    Accessing it easterly is a bonus not intention.

    but even so my Question still stands.
     
    Last edited: Dec 25, 2013
  8. JohnnyA

    JohnnyA

    Joined:
    Apr 9, 2010
    Posts:
    5,039
    C# doesn't have globals, a global is a definition of the scope of a variable, and all variables are tied to the lifetime of a class in c#. A public member variable is scoped to an instance so it is certainly not global. A public static variable is still tied to the scope of the class but pragmatically it serves a similar purpose.

    As to singleton usage there is no right or wrong, however common wisdom* is that the singleton pattern** is a very reasonable solution for manager type objects where the need for multiple instances is highly unlikely.


    * https://www.google.com.au/search?q=unity+singleton+pattern&oq=unity+singleton+pattern
    ** Or a psuedo-singleton pattern given the nature of MonoBehaviours.
     
    Last edited: Dec 26, 2013
  9. LightStriker

    LightStriker

    Joined:
    Aug 3, 2013
    Posts:
    2,716
    That's what I'm talking about. You assume that when you use "static", it's because there's a flaw in your design. I disagree.

    If I code a save game manager, there's no need to have any instance of it. There's no way, ever, that I would wake up one morning saying "Oh, let's run many instances of that". Another example, I have an AssetBundle entry point. There's no need for that to exist on a GameObject and there's no need for that to ever exist in more than one spot. On top, everything everywhere must be able to access it to retrieve the different downloaded bundles. By design, the best solution is a static class. Or look at Unity "Resources" class, it's a sealed static class.

    Static is a tool, like any other tool and it serves a specific purpose. Use it badly, and yes it's an error. Use it properly, and it serves its function like any other keyword of a coding language.

    And just to be clear to people who don't understand the different keywords here;

    static; flag a member to make it belong to the type instead of a specific object.

    sealed; prevents other classes from inheriting from the class flagged with it.

    singleton; code pattern that prevent multiple instances of the same class from existing. Usually in the form of;

    Code (csharp):
    1.  
    2. public class MySingleton
    3. {
    4.     private static MySingleton instance;
    5.  
    6.     // Readonly Property, self-initialize an unique instance if none exist.
    7.     public static MySingleton Instance
    8.     {
    9.         get
    10.         {
    11.             if (instance == null)
    12.                 instance = new MySingleton();
    13.  
    14.             return instance;
    15.         }
    16.     }
    17.  
    18.     // Private constructor so no other class can create an instance.
    19.     private MySingleton() { }
    20. }
    21.  
    public; Allow a member item to be accessed from an external source.

    protected; Allow a member item to only be accessed from internal or derived source.

    private; Allow a member item to only be accessed from its owner.

    There's lot of reason why you don't want to "static" everything or to "public" everything. It happens often that I want each instances of an object to have it's own variable. For example, each GameObject has a non-static position in space. If it was static, every GameObject in existance would be at the same position. There's also reason why I don't want everything to be public. Lot of variable I created are used internally and are switched of value only at specific times and for specific reason. If anybody could switch those while something is happening internal, it would most likely break its behaviour. Imagine shutting down the electrical system of a car while its running. Usually, you want that to happen only when you're parked and you shutdown the engine. (Yeah, my alternator died on me a few hours ago)

    There's also reason why you would want a member to be static. An object factory is a good example. Another is;

    Code (csharp):
    1.  
    2. public class DescriptorAttribute
    3. {
    4.     public static DescriptorAttribute GetDescriptor(Type type)
    5.     {
    6.         object[] obj = type.GetCustomAttributes(typeof(DescriptorAttribute), true);
    7.  
    8.         if (obj.Length == 0)
    9.             return null;
    10.         else
    11.             return (obj[0] as DescriptorAttribute);
    12.     }
    13. }
    14.  
    In the above code, it would make no sense for this method to not be static. The method retrieves an instance of that attribute on a specific type. The method itself return an instance... And since I had no instance previously known to call that method on, it has to be static.

    Also note that static is quite useful to reduce memory usage. Let's consider;

    Code (csharp):
    1.  
    2. private static Texture addButton;
    3.  
    4. public static Texture AddButton
    5. {
    6.     get
    7.     {
    8.         if (addButton == null)
    9.             addButton = Helper.Load(EditorResources.Add);
    10.  
    11.         return addButton;
    12.     }
    13. }
    14.  
    Which is part of a EditorWindow. The EditorWindow itself can exist in multiple instances. However, the texture it's using has no reason to have multiple instances loaded in memory. In this case, every instances of that panel will use the same pooled resources.

    Frankly, I would hire a coder who use static while knowing why he uses it, over one who try to never use it but doesn't know why or when he should be using it, or think it's a flaw when he uses one.
     
    eses likes this.
  10. softwizz

    softwizz

    Joined:
    Mar 12, 2011
    Posts:
    793
    Because the devil will eat your shoes :twisted:
     
  11. Brainswitch

    Brainswitch

    Joined:
    Apr 24, 2013
    Posts:
    270
    Thank you for your post (only quoting last part since it was rather long). I often see people writing against static and singleton in a fanatically way, and it saddens me to see some people swear never to use static and singletons and teach that to others. Both static and singletons have their usages, as you explained quite well.
     
  12. FireBolt-Studios

    FireBolt-Studios

    Joined:
    Dec 29, 2012
    Posts:
    58
    I know this post is very old, but I had to comment :)

    Never say never, cant argue with that post LightStriker, a shame you had to spend so long giving us a lesson there ;) on point though, this exactly the post I was looking for, if I read somewhere "Dont Use This Method" I always have to learn how it works since I understand it's usually there for a reason, I program by the neccesatity so that last statment I quoted made me chuckle, programming is two parts mindset and one part knowledge, knowledge is easily obtained if you know where to look but if your dont have the mindset to take on the information and apply it where its needed you will fall short!
     
  13. StarManta

    StarManta

    Joined:
    Oct 23, 2006
    Posts:
    8,745
    Well, occasionally, that reason is simply because that code is badly designed, and/or started off being badly designed and now must keep them around for the sake of legacy. I would argue that GameObject.Find and transform.eulerAngles are two examples of this from Unity - there is always a better solution than GameObject.Find in any given scenario, and Euler angles are unreliable to the point of uselessness for any situation except for setting a rotation with human-readable angle values. So, "Don't use this method" does sometimes have merit. (Though if you're simply saying that you shouldn't blindly accept "Don't use this method" until you understand the reason why, then we're in agreement, hence the links above.)
     
  14. FireBolt-Studios

    FireBolt-Studios

    Joined:
    Dec 29, 2012
    Posts:
    58
    I agree with you there, I was refereing to the "blindly accept" stance on that statment indeed. Although I do agree with you that there are certain functions and methods that are badly implemented I will however disagree when it comes to their usabiltiy. GameObject.Find is agreeably a very bad method to use due to the fact that it iterates over every Object in the scene, terrible for runtime or continous referencing but I do use it ocassionaly within the scope of editor extensions sometimes when called once or at very few places so to save convoulted setups to get one or two Objects. Also the same goes for Transform.EulerAngles, you are right in the fact that its very inacurrate but still I will use it if i need to set explicit rotations like snapped camera views, due to its simplicity.

    Scope defines necessity, it should be "Dont use this method in this situation." GameObject.Find when spawning projectiles, definatly not gonna be good. Full 3D camera rotations using Transform.EulerAngles, good luck with that. But as stated above even one situation where it is ok to use a method negates any connotations of "Dont use this method."

    I didnt want to make this reply a debate on method usuage but i will say in a certain situations that all methods are ok to use, it just where and when, and most of us will see that, when we come across that rare situation where you would actually use a "Dont use this method" method... haha! Although in my humble opinion the closest method to "Dont use this method" would definatly be GameObject.Find! ;)