[ACCEPTED]-Are there any viable alternatives to the GOF Singleton Pattern?-singleton

Accepted answer
Score: 97

To understand the proper way to workaround 16 Singletons, you need to understand what 15 is wrong with Singletons (and global state 14 in general):

Singletons hide dependencies.

Why is that important?

Because 13 If you hide the dependencies you tend to lose track of the amount of coupling.

You might argue that

void purchaseLaptop(String creditCardNumber, int price){
  CreditCardProcessor.getInstance().debit(creditCardNumber, amount);
  Cart.getInstance().addLaptop();
}

is simpler than

void purchaseLaptop(CreditCardProcessor creditCardProcessor, Cart cart, 
                    String creditCardNumber, int price){
  creditCardProcessor.debit(creditCardNumber, amount);
  cart.addLaptop();
}

but 12 at least the second API makes it clear exactly 11 what the method's collaborators are.

So the 10 way to workaround Singletons is not to use 9 static variables or service-locators, but 8 to change the Singleton-classes into instances, which 7 are instantiated in the scope where they 6 make sense and injected into the components 5 and methods that need them. You might use 4 a IoC-framework to handle this, or you might 3 do it manually, but the important thing 2 is to get rid of your global state and make 1 the dependencies and collaborations explicit.

Score: 77

Alex Miller in "Patterns I Hate" quotes the following:

"When 2 a singleton seems like the answer, I find 1 it is often wiser to:

  1. Create an interface and a default implementation of your singleton
  2. Construct a single instance of your default implementation at the “top” of your system. This might be in a Spring config, or in code, or defined in a variety of ways depending on your system.
  3. Pass the single instance into each component that needs it (dependency injection)
Score: 14

The finest solution I have came across is 18 using the factory pattern to construct instances 17 of your classes. Using the pattern, you 16 can assure that there is only one instance of 15 a class that is shared among the objects 14 that use it.

I though it would be complicated 13 to manage, but after reading this blog post 12 "Where Have All the Singletons Gone?", it seems so natural. And as an aside, it 11 helps a lot with isolating your unit tests.

In 10 summary, what you need to do? Whenever an 9 object depends on another, it will receive 8 an instance of it only through its constructor 7 (no new keyword in your class).

class NeedyClass {

    private ExSingletonClass exSingleton;

    public NeedyClass(ExSingletonClass exSingleton){
        this.exSingleton = exSingleton;
    }

    // Here goes some code that uses the exSingleton object
}

And then, the 6 factory.

class FactoryOfNeedy {

    private ExSingletonClass exSingleton;

    public FactoryOfNeedy() {
        this.exSingleton = new ExSingletonClass();
    }

    public NeedyClass buildNeedy() {
        return new NeedyClass(this.exSingleton);
    }
}

As you will instantiate your factory 5 only once, there will be a single instantiation 4 of exSingleton. Every time you call buildNeedy, the 3 new instance of NeedyClass will be bundled 2 with exSingleton.

I hope this helps. Please 1 point out any mistakes.

Score: 9

You shouldn't have to go out of your way 15 to avoid any pattern. The use of a pattern 14 is either a design decision or a natural 13 fit (it just falls into place). When you 12 are designing a system, you have a choice 11 to either use a pattern or not use the pattern. However, you 10 shouldn't go out of your way to avoid anything 9 that is ultimately a design choice.

I don't 8 avoid the Singleton Pattern. Either it's 7 appropriate and I use it or it's not appropriate 6 and I don't use it. I believe that it is 5 as simple as that.

The appropriateness (or 4 lack thereof) of the Singleton depends on 3 the situation. It's a design decision that 2 must be made and the consequences of that 1 decision must be understood (and documented).

Score: 9

Spring or any other IoC-Container does a 4 reasonably good job in that. Since the classes 3 are created and managed outside the app 2 itself, the container can make simple classes 1 singletons and inject them where needed.

Score: 6

Monostate (described in Robert C. Martin's 8 Agile Software Development) is an alternative 7 to singleton. In this pattern the class's 6 data are all static but the getters/setters 5 are non-static.

For example:

public class MonoStateExample
{
    private static int x;

    public int getX()
    {
        return x;
    }

    public void setX(int xVal)
    {
        x = xVal;
    }
}

public class MonoDriver
{
    public static void main(String args[])
    {
        MonoStateExample m1 = new MonoStateExample();
        m1.setX(10);

        MonoStateExample m2 = new MonoStateExample();
        if(m1.getX() == m2.getX())
        {
            //singleton behavior
        }
    }
}

Monostate has 4 similar behavior to singleton but does so 3 in a way where the programmer is not necessarily 2 aware of the fact that a singleton is being 1 used.

Score: 4

The singleton pattern exists because there are situations 25 when a single object is needed to provide a set of services.

Even if this is the case I still 24 consider the approach of creating singletons 23 by using a global static field/property representing the instance, inappropriate. It's 22 inappropriate because it create a dependency 21 in the code between the static field and 20 the object not, the services the object 19 provides.

So instead of the classic, singleton 18 pattern, I recommend to use the service 17 'like' pattern with serviced containers, where instead of using 16 your singleton through a static field, you 15 obtain a reference to it through a a method 14 requesting the type of service required.

*pseudocode* currentContainer.GetServiceByObjectType(singletonType)
//Under the covers the object might be a singleton, but this is hidden to the consumer.

instead 13 of single global

*pseudocode* singletonType.Instance

This way when you want to 12 change type of an object from singleton 11 to something else, you'll have and easy 10 time doing it. Also as an and added benefit 9 you don't have to pass around allot of object 8 instances to every method.

Also see Inversion of Control, the 7 idea is that by exposing singletons directly 6 to the consumer, you create a dependency 5 between the consumer and the object instance, not 4 the object services provided by the object.

My 3 opinion is to hide the use of the singleton 2 pattern whenever possible, because it is 1 not always possible to avoid it, or desirable.

Score: 2

If you're using a Singleton to represent 4 a single data object, you could instead 3 pass a data object around as a method parameter.

(although, I 2 would argue this is the wrong way to use 1 a Singleton in the first place)

Score: 1

If your issue is that you want to keep state, you 10 want a MumbleManager class. Before you 9 start working with a system, your client 8 creates a MumbleManager, where Mumble is 7 the name of the system. State is retained 6 through that. Chances are your MumbleManager 5 will contain a property bag which holds 4 your state.

This type of style feels very 3 C-like and not very object like - you'll 2 find that objects that define your system 1 will all have a reference to the same MumbleManager.

Score: 0

Use a plain object and a factory object. The 4 factory is responsible for policing the 3 instance and the plain object details only 2 with the configuration information (it contains 1 for example) and behaviour.

Score: 0

Actually if you design right from scratch 24 on avoiding Singeltons, you may not have 23 to work around not using Singletons by using 22 static variables. When using static variables, you 21 are also creating a Singleton more or less, the 20 only difference is you are creating different 19 object instances, however internally they 18 all behave as if they were using a Singleton.

Can 17 you maybe give a detailed example where 16 you use a Singleton or where a Singleton 15 is currently used and you are trying to 14 avoid using it? This could help people to 13 find a more fancy solution how the situation 12 could be handled without a Singleton at 11 all.

BTW, I personally have no problems with 10 Singletons and I can't understand the problems 9 other people have regarding Singletons. I 8 see nothing bad about them. That is, if 7 you are not abusing them. Every useful technique 6 can be abused and if being abused, it will 5 lead to negative results. Another technique 4 that is commonly misused is inheritance. Still 3 nobody would say inheritance is something 2 bad just because some people horribly abuse 1 it.

Score: 0

Personally for me а much more sensible way 6 to implement something that behaves like 5 singleton is to use fully static class(static 4 members , static methods , static properties). Most 3 of the time I implement it in this way (I 2 can not think of any behaviour differences 1 from user point of view)

Score: 0

I think the best place to police the singleton 18 is at the class design level. At this stage, you 17 should be able to map out the interactions 16 between classes and see if something absolutely, definitely 15 requires that only 1 instance of this class 14 is ever in existence at any time of the 13 applications life.

If that is the case, then 12 you have a singleton. If you are throwing 11 singletons in as a convenience during coding 10 then you should really be revisiting your 9 design and also stop coding said singletons 8 :)

And yes, 'police' is the word I meant 7 here rather than 'avoid'. The singleton 6 isn't something to be avoided (in the same 5 way that goto and global variables aren't 4 something to be avoided). Instead, you should 3 be monitoring it's use and ensuring that 2 it is the best method to get what you want 1 done effectively.

Score: 0

I use singleton mostly as "methods container", with 7 no state at all. If I need to share these 6 methods with many classes and want to avoid 5 the burden of instantiation and initialization 4 I create a context/session and initialize 3 all the classes there; everything which 2 refers to the session has also access to 1 the "singleton" thereby contained.

Score: 0

Having not programmed in an intensely object-oriented 22 environment (e.g. Java), I'm not completely 21 up on the intricacies of the discussion. But 20 I have implemented a singleton in PHP 4. I 19 did it as a way of creating a 'black-box' database 18 handler that automatically initialized and 17 didn't have to be passed up and down function 16 calls in an incomplete and somewhat broken 15 framework.

Having read some links of singleton 14 patterns, I'm not completely sure I would 13 implement it in quite the same way again. What 12 was really needed was multiple objects with 11 shared storage (e.g. the actual database 10 handle) and this is pretty much what my 9 call turned into.

Like most patterns and 8 algorithms, using a singleton 'just because 7 it's cool' is The Wrong Thing To Do. I needed 6 a truly 'black-box' call that happened to 5 look a lot like a singleton. And IMO that's 4 the way to tackle the question: be aware 3 of the pattern, but also look at it's wider 2 scope and at what level it's instance needs 1 to be unique.

More Related questions