« Sending People Home | Main | Team Equilibrium »

October 30, 2006

Comments

Name

There's no need to break singleton. For example, I created a class method for my database connection singleton which sets the base class to create. For testing, I use a connection to an in-memory SQLite database. For production, it's set by configuration options. In both cases, there's no need for more than one instance of the class.

Poster from Reddit

"In both cases, there's no need for more than one instance of the class."

That's not the issue. The issue is: is there a need to specifically limit your entire design to only ever be able to connect to one and only one database and should everything have access to it at all times?

keithb

Funnily enough this very issue came up on a client site a little while ago. One of the developers wandered over and asked me, all innocent-like, if I might just happen to know an easy way to get JUnit to run different tests under different classloaders...

Seems to me that the GoF did us a disservice in the way they illustrated Singleton, as an implemenation choice: thus is born the one-and-only db connection and so forth with all the trouble they bring.

But Singleton is pretty harmless if used to implement value objects that model a domain concept with a single unique instance (or multiple indistinguishable instances, if you think that's different). I'm thinking of the single instances of True and False in the Smalltalk image, for instance. In the domain of Boolean algebra (which is being modelled) all "T"s are T and all "F"s are F. Singleton provides a good way to deal with that. Otherwise, pretty pernicious.

Maybe Singleton is taking over from Visitor as the "whipping boy of patterns".

MrChucho

I've encountered this problem recently using Ruby. Thankfully, with Ruby I can create a singleton of my Singleton class for use in my unit tests. In this test-specific singleton I can add "reset" or "clear" method to reset the state. Assuming I have a singleton called "OnlyOne":

def test_singleton
class << OnlyOne.instance
def reset
# reset state
end
end

OnlyOne.instance.modify_state
OnlyOne.instance.reset
end

* Code doesn't seem to keep its formatting and it wasn't clear whether or not HTML is supported...

Eric

Just had numerous problems with this same instance. A cache object that in and of itself was too big, with 100+ unrelated methods - in some cases the methods were grouped together in the header file via comments. If only there was some sort of C++ structure to group methods and data together in an ...what's the word..object...

Anyway it kept kicking my butt and I turned it into a fingleton for testing purposes. Unfortunately TDD is not universally accepted at my company, and as such I may have to go to great lengths to justify breaking the design at code review.

Hey Michael. Your buddies over at ObjectMentor just changed the entire fitnesse.org blog, and it became very difficult to find a copy of CPPUnit Lite. Any chance you'll put a copy in one location that's more easily googlable? I needed it this morning and hunted for a long time before I found it on the old fitness site.

Ricky Clarkson

Singletons only really cause issues when they are used for global variables, or for external resources (almost the same thing).

We would probably have left the global variable behind in the 80s or earlier if the GoF hadn't glorified it by calling it a Singleton.

Willem Bogaerts

The testing problems with Singletons have made me come up with a design pattern: the Half-A-Singleton. This pattern is halfway between the "using global variable" code and the "pass everything around" code. To make it simple: it makes passing the Singleton's instance optional. So you CAN pass it for tests, but you can still leave a lot of production code intact. See http://www.w-p.dds.nl/pathalfs.php?STYLE=4

The comments to this entry are closed.