Singletons aren't bad ... or are they?

Discussion in 'Resources' started by kumpelblase2, Mar 12, 2014.

Thread Status:
Not open for further replies.
  1. Hey everyone :)

    In my other thread, where I talked about design patterns, I stated that a Singleton is definitely not a bad thing and might even be considered good practice. Now I want to elaborate on that again, because is this really true? I mean, leaving out the common answer here on the forum claiming that if you don't handle it properly it is definitely bad, because you can bring that up for everything. So are there still occasions or logical reasons for it to be considered bad?

    The answer is yes and no. It really depends on how you look at it.
    The idea of having a single instance of an object throughout the life of an application is definitely not bad at all and is really needed in some cases. Moreover, it makes many things way easier and thus keeps the code cleaner. Even the static instance aspect of it is not the worrying part. So what's wrong then?

    The real issues pops up when you start to run tests on those singletons. I mean, you can still do all your assertion tests, but at soon as you need to mock your singleton you start to see the issue; You can't mock it at all. The static method and private instance make it impossible for you to access the actual instance and mock it. In most scenarios, you might get away without mocking at all, but we need to see the whole picture. As soon as we want to test another class which depends on that singleton, we're screwed. There's no way for use to change the behavior in that case, even though we'll probably would need to. This also brings me to my next point. We don't directly see what a class really has of dependencies. We don't know that it uses this given singleton until we either get a NPE or look into the methods we're testing. This is definitely not great. I mean, sure, we won't run into this sort of issues at runtime, but tests should still be done and should still be possible to do, even in such an environment. In fact, those tests should ensure that we don't run into NPE's of those singletons at all times.

    But what about loggers? They're singletons too, right? Yes, but you have to separate them from the other ones. Singletons like loggers don't interfere with your program logic, they can easily be just left out and your program would still work completely fine. Again, there will be instances where you want things to be logged and thus probably still need to inject a mocked logger or something along those lines, but it's still far less worse than the things mentioned above.

    So do we just blame it on the tests and continue having fun with Singletons? Yes, errr no. Sort of. Testing is great so we can't just put it away. We just need to keep in mind certain things. Make the dependencies of a class visible by requiring them inside a constructor instead of using a static getter method. This already resolves most of the issues that'll come up. Apart from that, there's not really that much you can do without breaking the idea of a singleton, wich is not really what we're aiming for either. As you can see, the issue is not the idea itself, it is the implementation.

    I hope you enjoyed reading my post and I wish you a nice day :)
    ~kumpelblase2.
     
    mazentheamazin, glen3b and Bart like this.
  2. Offline

    ccrama

    kumpelblase2 One thing that I want to know is when would you really use singletons? I mean in a different application than your main class. Are there any examples you have of plugins that implement this?
     
  3. Offline

    SoThatsIt

    Listener classes, Arena or Player handlers, plugin apis, there are many applications where they are useful
     
    ccrama likes this.
  4. Offline

    drtshock

    Example of a plugin of mine using singletons https://github.com/drtshock/Obsidia.../snw/obsidiandestroyer/ObsidianDestroyer.java

    Example of using a singleton other than the main class https://github.com/drtshock/Obsidia...oyer/listeners/EntityExplodeListener.java#L29
     
    ccrama likes this.
  5. Offline

    xTrollxDudex

    kumpelblase2
    I'd like to point out that an instance of the "singleton" is not really needed. Joshua Bloch mentions that a relatively new (or old) implementation of a singleton is using an enum class...
    PHP:
    public enum Singleton {
        
    INST;

        public 
    void foo() { /* ... */ }
    }
    PHP:
    Singleton.INST.foo();
    He adds that Serialization will never make a new instance on an enum based Singleton.

    And did I say that it doesn't require and instance field yet?
     
  6. xTrollxDudex That still leaves us with the same problem, if not make it even worse. Any other singleton you could still mock when you'djust chage the visibility or add a setter, but using an enum makes that completely impossible.
     
  7. Offline

    ccrama

  8. Offline

    MrTwiggy


    Errr, Listeners & Arenas aren't usually good candidates for the Singleton pattern. There isn't much use for accessing a listener instance usually, and 'Arena's usually have multiple instances (one for each unique arena). The Singleton pattern is most useful when you have a class that should only have one single easily accessible instance.

    Two of the most common types of objects for singleton patterns (at least in my experience) when coding Bukkit plugins are actual JavaPlugin classes so that you can access your plugin instances without having to constantly pass them around to various objects, and for managers. It's quite common that you require some sort of 'Manager' to manage a single set of objects.
     
  9. Offline

    Jnorr44

    Utilities classes are typically singletons.
     
  10. Offline

    MrTwiggy


    I think that's actually one place that Singletons are often mis-used. Most utilities classes should utilize static methods rather then defaulting to a singleton design.
     
    bobacadodl and Garris0n like this.
  11. Offline

    SoThatsIt


    i was talking about handlers "arena or player handlers", i agree though that using them for a single arena object is kinda un-needed.
     
Thread Status:
Not open for further replies.

Share This Page