Hacker News new | ask | show | jobs
by kentonv 3991 days ago
Depends on what you mean by "singleton". If you define it loosely as "a type of which there is only one instance", fine, no problem -- of course those will exist. But if you define it as "globally-accessible mutable state", then the problems start. Usually, the "singleton pattern" is explicitly a technique for doing the latter.

> For instance, you don't want to end up creating multiple objects that read the configuration file, when one is enough.

Sure. But that doesn't mean the config file reader has to be globally-accessible. Instead, try allocating it on the stack in your main() function, then passing the object into each component that needs to see it. Better yet, only pass each component a sub-object(s) of the config which applies specifically to that component.

Now you have a bunch of useful benefits:

- Readability: You can clearly see and follow what components are affected by what parts of the config file.

- Testability: Unit tests can easily provide a test configuration.

- Maintainability: If some day you realize that you need to create two instances of some component and configure them differently, it's easy to do that without rewriting tons of code or introducing horrible "namespacing" hacks.

- Security: If your config file contains anything sensitive (say, database credentials), it's no longer the case that every damned module in the whole system has the ability to read those secrets. In fact, if your language is memory-safe and bans mutable global state, you can trivially sandbox any piece of code by simply not passing it references to anything it shouldn't be able to access. (This is called "capability-based security" or "object capabilities", and it works.)

Extended argument (which I wrote many years ago...):

http://www.object-oriented-security.org/lets-argue/singleton...

1 comments

Nailed it. It's fine to use a singleton, but don't call it from within every class you use it in. Just pass a reference to the instance of the singleton. Call it once in the outermost scope.
Just wondering what value the singleton provided if you only obtain it once. Isn't the purpose so you can obtain it whenever you want? If you just use a regular object, you run the risk of accidentally making another instance somewhere else, but you always have that risk with any regular object anyway.
It's kind of OK to use, as long as you don't call it all over the place and render your code untestable such that it can't be mocked out, but I'm not a huge fan of it. It's really a matter of opinion at that point.