94

Let's face it. The Singleton Pattern is highly controversial topic with hordes programmers on both sides of the fence. There are those who feel like the Singleton is nothing more then a glorified global variable, and others who swear by pattern and use it incessantly. I don't want the Singleton Controversy to lie at the heart of my question, however. Everyone can have a tug-of-war and battle it out and see who wins for all I care. What I'm trying to say is, I don't believe there is a single correct answer and I'm not intentionally trying inflame partisan bickering. I am simply interested in singleton-alternatives when I ask the question:

Are their any specific alternatives to the GOF Singleton Pattern?

For example, many times when I have used the singleton pattern in the past, I am simply interested in preserving the state/values of one or several variables. The state/values of variables, however, can be preserved between each instantiation of the class using static variables instead of using the singleton pattern.

What other idea's do you have?

EDIT: I don't really want this to be another post about "how to use the singleton correctly." Again, I'm looking for ways to avoid it. For fun, ok? I guess I'm asking a purely academic question in your best movie trailer voice, "In a parallel universe where there is no singleton, what could we do?"

Community
  • 1
  • 1
CodingWithoutComments
  • 35,598
  • 21
  • 73
  • 86
  • What? It's neither good nor bad, but how can I replace it? For all the folks who say it's good -- don't participate. All you folks that say it's bad, prove it by showing me how I can live without it. Sounds Argumentative to me. – S.Lott Oct 02 '08 at 12:59
  • @CodingWithoutComents: did read the whole post. That's how I got the sense of "don't reply if you thing Singletons are ok". – S.Lott Oct 02 '08 at 13:48
  • 2
    Well, if that's how it came across I apologize. I thought I took significant steps to avoid polarization. I thought I asked the question in a way that both lovers and haters of Singletons could both come away with that as a programmer we all have choices -- that their is never only one correct way – CodingWithoutComments Oct 02 '08 at 14:17
  • If I use Singletons, I have no possible contribution on how to work around them. Sounds polarizing to me. – S.Lott Oct 02 '08 at 18:44
  • 9
    I use Singletons everyday but does that stop me from thinking that there might possibly be a better way to do things? Design Patterns have only been around for 14 years. Do I take them as biblical truth? Do we stop trying to think outside the box? Do we not try to advance the discipline of CS? – CodingWithoutComments Oct 02 '08 at 20:49
  • All true. I agree with looking for a better way. I just can't understand the 1st paragraph of the question. It asks one thing: how NOT to use Singletons; I find the rest of the stuff on Controversy confusing and off-task. – S.Lott Oct 02 '08 at 20:56
  • OK. Re-reading it a few times, I can now see where you are coming from. I'm definitely going to try to re-word a few things tonight. And I'll be honest, the controversy stuff is a bit off-task -- I just kind of saw it as an attention grabber. – CodingWithoutComments Oct 02 '08 at 21:08

16 Answers16

97

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

Singletons hide dependencies.

Why is that important?

Because 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 at least the second API makes it clear exactly what the method's collaborators are.

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

Rasmus Faber
  • 48,631
  • 24
  • 141
  • 189
  • +1 For discussing the root of the problem, not just how to work around it. – Phil Apr 01 '12 at 14:54
  • 9
    In a full-fledged multi-tiered application, the second method often creates a massive amount of unnecessary code. By polluting middle tiers' code with logic to carry through to lower tiers, objects which are otherwise unnecessary at that level, aren't we creating dependencies which needn't be? Say tier 4 in a navigation stack initiates a background action, like a file upload. Now say you want to alert the user when it completes but by then, the user might be in a totally different part of the application which only shares tier 1 in common with the initiating view. Tons of unneeded code... – Hari Honor Jul 15 '12 at 14:32
  • 1
    @RasmusFaber A Singleton pattern does not hide dependencies. You're complaint about hiding dependencies is a separate concern from the pattern. It is true that the pattern makes it easy to make this mistake, but it is very possible to execute IoC and Singleton pattern together in harmony. For example, I can create a 3rd party lib that needs special lifecycle management of its instances, and anyone who uses my lib should still "pass" an instance of my singleton to their classes using classic Dependency Injection rather than "sky hook" my singleton from every pointcut. – Martin Bliss Apr 30 '13 at 13:49
  • @HariKaramSingh you can use subscribe/publish pattern or system-wide event bus (which must be shared across all concerned parties, not a singleton) to work-around this. – Victor Sorokin May 07 '13 at 16:18
  • @VictorSorokin, same problem if the manager is not a singleton - you have to pass the manager all over the place creating the same unnecessary code I mention above. – Hari Honor May 11 '13 at 13:23
  • 4
    Also pub/sub or observer patterns can be just as bad wrt "losing track of coupling" as anyone who's had to step debug through a framework which relies heavily on them will attest to. At least with singleton's, the method name being invoked is at the same place as the invoking code :) Personally, I think all these strategies have their place and none can be implemented blindly. Sloppy coders will make spaghetti out of any pattern and responsible coders needn't burden themselves excessively with ideological limitations to create elegant code. – Hari Honor May 11 '13 at 13:29
  • "get rid of your global state" - erm, what if you need global state? That's kind of the idea of a singleton. – Jez Mar 10 '16 at 13:25
  • I think the example would be improved by only passing "current transaction specific" values to the method, and having the creditCardProcessor and cart obtained earlier and stored in member variables. – davidfrancis Sep 26 '17 at 14:02
77

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

"When a singleton seems like the answer, I find 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)
CodingWithoutComments
  • 35,598
  • 21
  • 73
  • 86
Jacek Szymański
  • 2,634
  • 20
  • 15
  • 2
    I know this is nigh 5 years old, but could you expand on this? I think I was taught that the right way to create a singleton was with an interface. I'd be interested if what I was doing was 'OK', and not as terrible as I've been told. – AncientSwordRage Apr 06 '13 at 18:16
14

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

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

In summary, what you need to do? Whenever an object depends on another, it will receive an instance of it only through its constructor (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 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 only once, there will be a single instantiation of exSingleton. Every time you call buildNeedy, the new instance of NeedyClass will be bundled with exSingleton.

I hope this helps. Please point out any mistakes.

seuvitor
  • 291
  • 1
  • 2
  • 10
  • 5
    to make sure your Factory is instantiated only once you need a private construtor and define the buildNeedy method as a static method. – Julien Grenier Oct 23 '08 at 01:26
  • 16
    Julien is right, this fix has a fundamental flaw, which is that you're implicitly saying you can only instantiate one factory. If you take the necessary precautions to ensure that only one factory is instantiated (ala what Julien said) you end up with... a singleton! In reality this approach just adds an unnecessary layer of abstraction on top of the singleton. – Bob Somers Jul 07 '09 at 03:35
  • There is another way to have only one Instance. You could instantiate your factory only once. No need to enforce this by the compiler. This also helps with unittests where you *want* a different instance. – frast Jul 12 '11 at 11:10
  • This is the best solution I've ever seen to the problem that is wrongly solved with singletons - adding dependencies without cluttering every method call (and therefore redesigning the interface and refactoring its dependencies). A slight modification is perfect for my situation where it's not important that there only be one instance of the "singleton", but it is important that everyone will share the same instance by default (the modification is: instead of using a factory, use static methods to externally set the common instance, and use that instance during construction). – meustrus Nov 26 '11 at 14:29
  • So basically the advantage of this approach is that you only have to shuffle around *one* object instance (the factory) rather than potentially a whole bunch of objects (for which you are choosing not to use Singletons)? – Hari Honor Jul 15 '12 at 14:38
  • Who said that we have to restrain objects from being instantiated multiple times? One argument against Singleton is that competent developers are normally competent enough not to instantiate a class several times. This said, having a singleton factory is not uninteresting. I don't see it as an unnecessary layer. Because what you are interested in is the class that will be generated. You want several instances so you can have several tests running and don't want the test to modify the state of the object but a factory's state shouldn't be modified from a test to another. – Bevelopper Jun 30 '20 at 10:15
9

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

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

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

Thomas Owens
  • 114,398
  • 98
  • 311
  • 431
  • I was going to say the same thing, but it doesn't quite answer his question :) – Swati Oct 02 '08 at 12:41
  • 2
    Please talk about in your answer when it is appropriate or not appropriate. Pretty Please. – CodingWithoutComments Oct 02 '08 at 12:42
  • It does answer the question. I don't have techniques for avoiding the use of the Singleton Pattern because I don't go out of my way to avoid it, and I don't think any developer should. – Thomas Owens Oct 02 '08 at 12:42
  • I don't think you can generalize when it is or is not appropriate. It's all project specific, and depends greatly on the design of the system in question. I don't use "rules of thumbs" for decisions like this. – Thomas Owens Oct 02 '08 at 12:44
  • Hmm. I don't get why this is getting voted down. I answered the question - What are your techniques for avoiding the use of the Singleton Pattern? - by saying that I don't have techniques because I don't go out of my way to avoid the pattern. Could the downvoters elaborate on their reasoning? – Thomas Owens Oct 02 '08 at 12:54
  • It is likely this has been downvoted because there is no explanation of when it is appropriate or not appropriate to use a singleton. Singletons make it quite easy to store global data for an application and share this data throughout the course of the program. Many developers would think this is a great benefit of singletons and would go on blindly using them without realizing there is a HUGE flaw in their design. Using singletons to store global data quickly becomes a dependency management nightmare and the application becomes nearly impossible to write automated tests for. – tjwrona1992 May 25 '18 at 17:35
9

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

Kai
  • 229
  • 1
  • 3
6

Monostate (described in Robert C. Martin's Agile Software Development) is an alternative to singleton. In this pattern the class's data are all static but the getters/setters 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 similar behavior to singleton but does so in a way where the programmer is not necessarily aware of the fact that a singleton is being used.

Mark M
  • 1,807
  • 2
  • 21
  • 40
  • This deserves more votes; I came here from Google looking for a MonoState refresher! – mahemoff Apr 21 '13 at 11:09
  • @Mark It seems to me that this design is very hard to lock down in terms of thread safety. Do I create an instance lock for each static variable in MonoStateExample, or do I create one lock that all properties leverage? Both have serious ramifications that are easily solved executed in a Singleton pattern. – Martin Bliss Apr 30 '13 at 13:52
  • This example is an alternate to Singleton pattern, but does not solve problems of Singleton pattern. – Sandeep Jindal Jun 13 '13 at 15:27
4

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

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

So instead of the classic, singleton pattern, I recommend to use the service 'like' pattern with serviced containers, where instead of using your singleton through a static field, you obtain a reference to it through a a method 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 of single global

*pseudocode* singletonType.Instance

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

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

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

Pop Catalin
  • 61,751
  • 23
  • 87
  • 115
  • I don't quite follow your example of serviced containers. Do you have an online resources you could link to? – CodingWithoutComments Oct 02 '08 at 13:17
  • Take a look at "Castle Project - Windsor Container" http://www.castleproject.org/container/index.html. Unfortunately it is very hard to find abstract publications about this topic. – Pop Catalin Oct 02 '08 at 13:36
2

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

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

David Koelle
  • 20,726
  • 23
  • 93
  • 130
1

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

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

plinth
  • 48,267
  • 11
  • 78
  • 120
  • Without advocating for or against Singleton, I must say that this solution is an anti-pattern. MumbleManager becomes a "God class" that contains all kinds of disparate knowledge, violating Single Responsibility. It may as well be a Singleton for all the application cares. – Martin Bliss Apr 30 '13 at 13:53
0

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

David
  • 14,047
  • 24
  • 80
  • 101
0

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

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

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

Mecki
  • 125,244
  • 33
  • 244
  • 253
0

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

user18834
  • 49
  • 1
  • 4
0

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

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

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

workmad3
  • 25,101
  • 4
  • 35
  • 56
  • 1
    I totally understand what you are saying workmad. And I completely agree. However, your answer still doesn't specifically answer my question. I didn't want this to be another question of "when is it appropriate to use the singleton?" I was just interested in viable alternatives to the singleton. – CodingWithoutComments Oct 02 '08 at 13:20
0

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

Manrico Corazzi
  • 11,299
  • 10
  • 48
  • 62
0

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

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

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

staticsan
  • 29,935
  • 4
  • 60
  • 73
-1

What do you mean, what are my techniques to avoid it?

To "avoid" it, that implies that there are many situations that I come across in which the singleton pattern is a naturally good fit, and hence that I have to take some measures to defuse these situations.

But there are not. I don't have to avoid the singleton pattern. It simply doesn't arise.

DrPizza
  • 17,882
  • 7
  • 41
  • 53