I wrote a standalone singleton class (scaffold) tonight that serves as a facade to a few other classes, including a template class and a view class. Templates and views are both named and instances of each are stored in the scaffold object. Templates can contain views and views can contain other views. A template and it’s contained views is rendered when:
scaffold->render('template_name')
Making scaffold a Singleton seemed like a good idea because:
- I want to control when and how the object is constructed
- I only want one instance (the gui will only be rendered once, regardless of the template which is rendered)
- All state can easily be released from the scaffold class (if, for testing reasons or whatever, I wanted to)
Does this seem like an acceptable use case? If not, what specific design considerations am I overlooking?
No religious wars, please. I didn’t include the language because I’m hoping for a language agnostic consideration, but I will say:
- Scripting language
- Single threaded
2
There are hardly any circimstances under which a singleton is legitimate (the only one that springs to mind is providing an interface to a hardware device or register which needs to be shared but for which it would be catastrophic if each program that accesses the resource did so at the same time). Singletons introduce far more difficulties than they do benefits, they are essentially global state and they create hidden dependencies, all of which makes unit testing far more difficult than it would be if you passed the dependencies in as parameters
The unique thing about Singletons is that you enforce that there can only be one instance at any given time. Singletons are somewhat appropriate when you have to enforce this; if being one-of-a-kind is convenient, but not absolutely required, you don’t need a Singleton.
There is no reason to hide the constructor: just make it publicly accessible, and provide a static method to get the global ‘default’ instance. Most of your codebase will use that, it’s accessible from anywhere (which isn’t necessarily a good thing; you’re trading safety for convenience), but if you decide that at some particular point you need a dedicated instance (e.g. for testing, or because the template engine carries some state that you need to mess with without affecting other parts of the codebase), you are free to create one.
1