-4

It is well known that Singletons are anti-patters for several reasons:

  1. tight coupling
  2. singletons are pathological liars
  3. no testability
  4. inheritance is not available
  5. you cannot program to interfaces, you program to implementations

But there is the code:

class ISingleton
{
protected:
    ISingleton() {}

public:
    virtual ISingleton& getInstance() = 0;
    virtual void doSomething() = 0;
    virtual ~ISingleton(){}
};

class SingletonA : public ISingleton
{
public:
    virtual SingletonA& getInstance() override
    {
        static SingletonA instance;
        return instance;
    }

    virtual void doSomething() override
    {

    }
};

class SingletonB : public ISingleton
{
public:
    virtual SingletonB& getInstance() override
    {
        static SingletonB instance;
        return instance;
    }

    virtual void doSomething() override
    {

    }
};

class DependsOnSingleton
{
private:
    ISingleton& m_singleton;

public:
    DependsOnSingleton(ISingleton& singleton)
        : m_singleton {singleton}
    {

    }

    void use()
    {
        m_singleton.doSomething();
    }
};

Do you see any of the problems in the code listed above? And it completely assures that a single instance can be created. You can see here direct dependency injection is used, it could also be used with DI containers too. I think people just misunderstand what Singleton is for. Do I miss something?

  • 1
    this doesn't seem like a question – DeadMG Sep 23 '16 at 7:12
  • "Do I miss something?" Doesn't it let you to answer me and say that the problem is... – Narek Sep 23 '16 at 7:13
  • 1
    I think you may confuse the singleton pattern with the case of a single implementation class. Single implementation classes, for example, for service interfaces are nothing unusual and not an anti-pattern. – Frank Sep 23 '16 at 7:15
7

Do you see any of the problems in the code listed above? And it completely assures that a single instance can be created.

No, it absolutely does not.

class SingletonC : public ISingleton
{
public:
    virtual SingletonC& getInstance() override
    {
        return *this;
    }

    virtual void doSomething() override
    {

    }
};

Now you can make as many instances as you want. The whole idea of getInstance doesn't even remotely make sense when it's a non-static method, since by definition, you must already have an instance in order to call it.

Also, your code is not testable, since the implementations of SingletonA and SingletonB can't be tested due to their statically stored mutable state, and they cannot accept interfaces DI-style since they are not constructed.

|improve this answer|||||
2

Since the getInstance method is non-static, that means you need to instantiate your class first. So if you want to have a instance of B, you need to make a "new B()" first. I don't see any values of this. If you do new A() getInstance() will return a instance of type A

If you want to use singletons without the problems that come with the patterns. Use injections (either at construction or using setter) like Spring does.

You have the benefits of the singleton with way less cons of it.

|improve this answer|||||

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

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