views:

631

answers:

8

Singleton is definitely one of the most misused and abused patterns out there. Many of us have been infected with Singletonitis at one point or another. Curiously, its close cousin Monostate is less famous and less used. What is your opinion of Monostate? Good or just as evil? Is it a better alternative to using Singleton? Would you also discourage its use as you would with Singleton?

+4  A: 

how about not using patterns just because?

update: abuse of singleton occurs because people add the pattern w/o justification. It often adds arbitrary constraint to no benefit. using monostate w/o justification is perhaps less harmful, but no more justified. if the universe won't collapse if there's more than one instance, than don't enforce it with a pattern - just create only one instance.

Dustin Getz
I disagree. If software is to ever evolve into a true building-block format, then we need to standardize the way things are done, similar to the way structural enginers have standardized various parts of bridge or building design. Patterns should always be used over roll your own if possible.
Mystere Man
The question doesn't suggest that one should use pattern for pattern's sake.Pattern is not a tool,it's the same theme that occurs again and again in software construction.If you identify such a pattern in your daily code design and know its pros/cons, it will help you craft better software.
Boon
"Don't enforce with it with a pattern" seems off as either way we are enforcing it with a pattern - in your case the pattern of "creating only one instance". Creating only one instance is not free either, it might mean methods or method signatures will need to added to pass the shared info around.
Boon
my way, its trivial to create another instance, like when you decide to make your display adapter code support a second monitor.
Dustin Getz
@MM: patterns should be used over roll-your-own when simpler
Dustin Getz
-1 for pattern bashing
Casebash
+4  A: 

Why are you assuming that people would discourage the use of Singletons? Making sweeping generalizations about Singletons is like making sweeping generalizations about gotos, global variables and so on. There is a place for all of them. None of these things are "evil", and their misuse doesn't make them bad to use, it just means they need to be used properly.

Tim Sullivan
People *do* discourage Singletons, to the point that Google have a tool to remove them from any Java code written by their employees! They of course have their uses (mostly caching/resource handling) but at the face of it, they are global variables and they make testing code a nightmare.
rjh
I've never had problems testing singletons. What is it that makes them nightmarish?
Tim Sullivan
Ditto - most features/patterns/functionality can be abused if used incorrectly; it doesn't make them inherently 'evil'.
RobS
You don't have to be 100% bad to be termed evil. With your logic, atomic bomb is not evil when used correctly. The problem is there is very few cases when atomic bomb can be used properly, therefore, it's ok to generalize it as evil and that's good enough for almost all discussions.
Boon
Boon: that's a false analogy, and not what I'm saying at all. Comparing a Singleton, something that is handy at best and awkward at worst, to something that can kill millions of people is kind of childish. Singletons are fine when used properly, and no one will die.
Tim Sullivan
Atomic bomb was used in the Second World War because its use was considered "proper" to stop the war,but one wonders if there must be other alternatives because of the damage inflicted? It's more of a sweeping generalization to say if something can be used properly,it cannot be termed evil.
Boon
Boon, I still don't buy it. The purpose of the atomic bomb is to destroy. The purpose of the singleton is to provide a single instance of a class. How exactly are these tools comparable? Sorry, man, but you're being ridiculous.
Tim Sullivan
They are not meant to be comparable,but as an analogy to show your generalization that "None of these things are evil,and their misuse doesn't make them bad to use,it just means they need to be used properly." collapses under its own weight,as some things are evil cuz its proper use is limited.
Boon
I'm not generalizing, I'm bucking against the generalization that those things are "evil". They're not, they're simply often mis- or over-used. Realistically, it's more like a knife than a bomb. Sure, you could kill someone with it, but it also has legitimate uses. In future, don't be so dramatic.
Tim Sullivan
+1  A: 

The deal with Monostate is that you need to know less about the implementation of the object in order to use it. In other words you save a few keystrokes because you don't have to call the objects getInstance method ( Singleton s = Singleton::getInstance; s.Method(); ) to get a reference to the object, you simply use normal language constructs ( Monostate ms; ms.Method(); ). A fine line indeed.

Every programming langauge construct can be labeled evil because every programming language contrsuct can be abused.

When used reasonably, I see neither one being "evil" or "good."

+2  A: 

The biggest problem I have with Monostate is that it can lead to confusion on the part of those using it. Generally speaking, if you create a new instance of an object, you expect it to be just that, a new instance, with its own state and lifecycle. I generally consider unexpected behaviors to be a bad thing, so I prefer the singleton, just because you know what your getting when you use it.

As for whether or not either pattern is evil, singletons tend to get misused, but then so do all of the other patterns, switch statements, for loops, or just about anything else you care to mention.

ckramer
+1  A: 

Here is an excerpt from page 127 of Design Patterns: Elements of Reusable Object-Oriented Software by Gamma, Helm, Johnson, and Vlissides.

Use the Singleton pattern when

  • there must be exactly one instance of a class, and it must be accessible to clients from a well-known access point
  • when the sole instance should be extensible by subclassing, and clients should be able to use an extended instance without modifying their code

Does it really make singletons evil just because they are misused and misunderstood?

Glenn
yes .
Dustin Getz
no .
Skurmedel
+3  A: 

According to this definition of Monostates, is this note:

"Monostates are evil in the same way that SingletonsAreEvil."

I don't necessarily agree. The basic premise is that Singletons and Monostates are global variables, and since Globals are evil, so too must be Singletons and Monostates.

The problem with this line of reasoning is that it doesn't take into account WHY globals are evil. Globals are evil primarily because they are variables that can be accessed outside the local scope accidentally, similarly to how non-typed languages often allow variables to be created simply by referencing them.

Singletons and Monostates can't cause the same kinds of problems, because it's virtually impossible to "accidentally" reference a global static, call it's instance method, then utilized the instance.

In other words, globals are evil because they cause subtle and hard to see problems. Singletons and Monostates do not cause the same kinds of problems, so I don't see them as evil for the same reasons, which is where most people seem to go wrong in this argument.

Now, can singletons and monostates cause other kinds of problems? Sure. Apparently, the TDD people hate them because they are hard to test correctly with automated testing. Ok, fine, but for those people that don't use TDD, those problems don't exist.

Of course singletons can be misused. People that use them simply to avoid passing an instance around are misusing them. I think Monostates are better for that than a singleton.

Many people propose factory patterns instead of singletons, but I feel that Factories are just fancy singleton generators. No, there is no static "instance" method, but it basically does the same thing (when a factory creates a single instance object that is). Factory.Create is no different from Singleton.Instance.

EDIT:

One aspect of Singletons and Monostates that is comparable to Globals is that they are shared, and thus not thread safe. While this is a concern if you plan to do multi-threaded apps, if you know this you can take steps to serialize access to the shared objects. So this is probably the only area where, generally, all three types can be thought of as causing troubles.

Mystere Man
Well said. One thing though, factories are not necessarily singleton generators. In fact, most of the time factories are used to generate actual class instance.
Boon
That's why i said "when a factory creates a single instance object that is".
Mystere Man
99% of the time when factory is used, it's used as virtual constructor (e.g. it returns one of its subclasses's instance based on an id passed in), not as singleton generators. So Factory.Create is almost always different from Singleton.Instance.
Boon
+5  A: 

Um, monostate is Singleton... so it has the exact same problems.

  • testing
  • hiding dependencies
  • inflexible
  • thread safety
  • global state makes it difficult to ensure correctness
That sums it up nicely. Neither Monostate *nor* Singleton are a good idea in general.
Randolpho
Monostate is not the same as singleton or I won't pose this question.https://segueuserfiles.middlebury.edu/xp/SingletonAndMonostate.pdf
Boon
In distinguishing singleton and monostate, this paper stops at technicalities - performance, polymorphism and syntax - all of which are specific to a Java implementation. It does not address the conceptual differences between singleton and monostate, because there are none.
Implementation differences can have effects on the rest of the system, so we can't just say A is B if they are conceptually the same. Would also love for you to elaborate on a few points you brought up: inflexibility, difficulty in ensuring correctness and hiding dependencies.
Boon
Inflexibility: You never know how much of something you're gonna need. Got a single printer today? They'll be two tomorrow.
Ensuring correctness: If all code has access to an object, it tends to make USE of that access. You end up with state being changed from seemingly unrelated modules which quickly becomes a hell to understand. It becomes impossible to state invariants, as there is no access control on the singleton.
Hiding dependencies: read http://misko.hevery.com/2008/08/17/singletons-are-pathological-liars/
Also search for singleton q's on SO, there have been plenty. As to the discussed Java implementation of monostate:I consider it to obscure the effect of code(which the posted paper misguidedly calls "transparency")and to me this is reason enough to avoid it. It's still just an impl of Singleton tho.
A: 

How about a class with a single instance, but without global access:

public class SingleInstance
{
    private static boolean exhausted = false;

    public SingleInstance()
    {
        if (exhausted)
        {
            throw new IllegalStateException("only one instance allowed");
        }
        exhausted = true;

        [...]
    }

    [...]
}

This avoids the problems of Singleton and MonoState, while it enforces and clearly communicates that there is only one instance.

starblue