1

I'm working on a small project and I've decided to move over from DI to singleton pattern. Although I know 2 ways to do singleton.

The first one is where every non-model class is a singleton. This means:

UserController
DatabaseHelper
ConfigurationModule
FriendComponent

Are all singletons, however:

User
UserFriendship
DatabaseConnection
DatabaseConfig

Aren't since they're all models.

However, the second way I know is:

I have one main singleton class (I'll use class Program as example). The class looking something like:

class Program
{
    private static Program _instance;
    private readonly DatabaseHelper _databaseHelper;

    public Program()
    {
        _databaseHelper = new DatabaseHelper();
    }

    public static Program GetInstance()
    {
        if (_instance == null) 
        {
            _instance = new Program();
        }

        return _instance;
    }
}

I know this is mainly subjective but I was wondering which of these 2 (or if both not) is best to use.

5
  • 6
    "I know this is mainly subjective but I was wondering which of these 2 (or if both not) is best to use." Neither. There is no excuse, ever, to inflict the singleton anti-pattern on a piece of code.
    – David Arno
    Commented Jul 10, 2018 at 7:41
  • Then what'd be the best way to do it without that, DI or god class which also appears to be bad from what I've heard?
    – Navine
    Commented Jul 10, 2018 at 7:42
  • @Navine try new
    – Ant P
    Commented Jul 10, 2018 at 7:43
  • @AntP What do you mean?
    – Navine
    Commented Jul 10, 2018 at 7:44
  • 1
    Why do you need to enforce there is only one? Either you have mutable global state, or you don't need to enforce only one
    – Caleth
    Commented Jul 10, 2018 at 8:25

2 Answers 2

11

I know this is mainly subjective but I was wondering which of these 2 (or if both not) is best to use.

Neither. There is no excuse, ever, to inflict the singleton anti-pattern on a piece of code.

If you need Program to be a singleton, then create it once and pass it around you application via constructor and method parameters. That is, after all, all that dependency injection is when stripped down to its pure form. If you are having trouble with DI then the chances are, you've dived head first into using a DI framework and ended up tying yourself in knots with its complexity. So start at the beginning: pass values around using parameters.

The singleton pattern is just a glorified global variable, with all the action at a distance problems that globals cause. It makes the code hard to maintain and very hard to test. So just don't use them, please.

14
  • 5
    While I agree with the main part of this answer (regarding DI frameworks vs. parameters), I think absolute statements like “there is no excuse, ever” are deeply unhelpful and intellectually lazy. On this site we see so many questions that stem from blindly following best practices. I don't think we should be encouraging that kind of thinking. Software designs are not morally right or wrong, there are just approaches that are more likely to work. I'd rather say: “In my experience, singletons are unnecessary or even problematic. We don't need them here because we can simply do X, Y, or Z.”
    – amon
    Commented Jul 10, 2018 at 9:33
  • 3
    @amon, I agree that too often some folk (and I'm one of them), use absolutes around coding rules, when "most of the time, you should not be using xxx" is better advice. But there are some cases where I feel that absolute position is justified. The singleton pattern is one such case in my view. So a simple challenge for you: provide me with a valid use case for where a static, globally accessible, singleton is the only viable solution and I'll accept I'm wrong to adopt that absolute position. Go... ;)
    – David Arno
    Commented Jul 10, 2018 at 10:05
  • 3
    I like the simple statement of absolute truth. We don't need to preface everything with "in my opinion" or suffix with "except for edge case x" people want succinct answers to their problems, not essays
    – Ewan
    Commented Jul 10, 2018 at 10:10
  • 4
    @Flater: you can still inject an object that loads something lazily and caches it without using the Singleton pattern.
    – Bossie
    Commented Jul 10, 2018 at 11:11
  • 3
    "A settings class which retrieves its data from an external dependency" -> except you don't want an external dependency when testing clients of settings
    – Caleth
    Commented Jul 10, 2018 at 13:25
2

Consider this:

If a singleton is the solution, then what is the problem?

But I only want one instance of a class!

Fine, then create a single instance.

But why paint yourself into a corner with a singleton when there is no upside? Consider the canonical example of logging. You might only want one log now, but you may want a number of them in the future.

Far from making code simpler, singletons tend to have their own specific syntax in code (and in frameworks too). There are a persistent blight on code bases (legacy ones in particular) and I suspect history will rightly judge these "silver bullets" as a mistake.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.