Solved Proper singleton use case?

Discussion in 'Spigot Plugin Development' started by vallas, Apr 19, 2020.

  1. I have lately been working on a gui library where there is a GuiManager class that handles the stack of user interfaces a player has open (meaning, when the top menu closes, the one below opens). It is imperative that only one instance exists per plugin as multiple instances within the same plugin would cause strange behavior.

    My first thought was to avoid the singleton pattern altogether and only create an instance in the plugin's onEnable method, and then pass it through a constructor where needed. But before publishing the library, I want to make sure that everything works in all cases and that it is developer friendly. This led me to think that a singleton might be the way to go, as a developer could not go wrong when accidentally creating a second instance somewhere. Would this be a correct use case of a singleton?
     
  2. That seems like a valid use case, provided that you're following standard practice, e.g. the singleton instance variable is private/static, the class constructor is private or protected (if private, then the class should be marked final as well to indicate that subclassing is not allowed), and the getInstance() method (or whatever you're calling it) is marked synchronized for thread-safety.

    (From this great guide on singletons: https://www.javaworld.com/article/2073352/core-java-simply-singleton.html; for more about the theory of singletons, see this humorous but informative guide: http://geekswithblogs.net/AngelEyes...u-but-youre-bringing-me-down-re-uploaded.aspx)
     
    • Useful Useful x 1
  3. Thank you for the extra information on the singleton pattern. Good thing you mentioned it, there are a lot of details there.
     
  4. Usage of the singleton pattern is mostly discouraged as it is considered an anti-pattern. It introduces a global state into your application, makes your code more complex, less useful and makes it a pain to re-use or test. You mentioned passing it through a constructor where needed, this is called dependency injection which is also the recommended way to go.

    This, however, doesn't mean that you can't get away with it in your current application. It's just that singletons are considered bad practise in the world of software engineering as they bring a lot of disadvantages with them.

    There's not really a source for this, you should just look it up for yourself, read some articles and decide for yourself whether you think your usage of the singleton pattern is justified or not.
     
  5. Singletons are very much a valid pattern. Whilst commonly abused, this doesn't make singletons any less valid.

    There are singletons within Java itself, such as the Runtime class - obviously there is only a single runtime environment, and so using a singleton for this class is a valid usage.

    A use case you might use yourself is a database controller class - obviously you only want one database connection pool for the entire application, so a singleton would be a valid use case in this instance also
     
  6. A singleton is indeed a valid pattern, but a highly discouraged pattern to use. If OP thinks a singleton is the way to go then definitely implement a singleton, but in 95% of the cases your design is flawed forcing you to implement the singleton.

    For actual design pattern reviews, we would need to see a class diagram.
     
  7. I want to thank you all for your very valuable insights. I have decided to move away from the singleton approach and will work towards a more stable build where multiple instances don't cause issues.