views:

777

answers:

11

Closed as exact duplicate of this question. But reopened, as the other Singleton questions are for general use and not use for DB access

I was thinking of making an internal data access class a Singleton but couldn't convince myself on the choice mainly because the class has no state except for local variables in its methods.

What is the purpose of designing such classes to be Singletons after all?
Is it warranting sequential access to the database which is not convincing since most modern databases could handle concurrency well?
Is it the ability to use a single connection repeatedly which could be taken care of through connection pooling? Or Is it saving memory by running a single instance?

Please enlighten me on this one.

+3  A: 

This question has been asked before I think. Have a look here

See this question:
http://stackoverflow.com/questions/228164/on-design-patterns-when-to-use-the-singleton

hhafez
Indeed it has. I edited it into your question. Hope you don't mind.
Joel Coehoorn
Thanks :) I add the wrong link initially but you also found a good one
hhafez
Not sure if that question, which is more general, is applicable to this question which is referring to a specific use, i.e. DB access.
Rob Wells
+3  A: 

I've found that the singleton pattern is appropriate for a class that:

  • Has no state
  • Is full of basic "Service Members"
  • Has to tightly control its resources.

An example of this would be a data access class.

You would have methods that take in parameters, and return say, a DataReader, but you don't manipulate the state of the reader in the singleton, You just get it, and return it.

At the same time, you can take logic that could be spread among your project (for data access) and integrate it into a single class that manages its resources (database connections) properly, regardless of who is calling it.

All that said, Singleton was invented prior to the .NET concept of fully static classes, so I am on the fence on if you should go one way or or the other. In fact, that is an excellent question to ask.

FlySwat
Be careful: this can still get you into trouble. I worked for a place that used a singleton in winforms app for the kind of data access your talking about, and when they needed to convert to a web app the singleton _killed_ performance because there could only be one connection for _all_ users.
Joel Coehoorn
Of course, the trick here is that it turned out the singleton did have state: the connection. But it's a very find distinction and easy to screw up.
Joel Coehoorn
Joel, a "getData" method should manage the connection internally, not a share a single connection in the class itself. That is state. Your probablem was that the singleton was poorly written.
FlySwat
@Jon Yeah, typically modern .NET DAO classes (singleton or otherwise) don't cache connections - but allow the connection pool to be handled by the driver. All of the .NET ADO drivers do this well.
TheSoftwareJedi
Could you elaborate on the 3rd bullet? I don't understand it. 'Resources' sounds like data members, i.e. state...
andreas buykx
andreas: Resources such as locally scoped resources (not class members, method members). IE, Get a connection from the pool, perform operation, release connection.
FlySwat
+1  A: 

The Singleton is a useful Design Pattern for allowing only one instance of your class. The Singleton's purpose is to control object creation, limiting the number to one but allowing the flexibility to create more objects if the situation changes. Since there is only one Singleton instance, any instance fields of a Singleton will occur only once per class, just like static fields.

Source: java.sun.com

Rene
sun's definition is about 10 years out of date.
Dustin Getz
+3  A: 

You probably wouldn't want to use a Singleton for the circumstances you describe. Having all connections to a DB go via a single instance of a DBD/DBI type class would seriously throttle your request throughput performance.

HTH

cheers,

Rob

Rob Wells
Elaborate, Unless you are multithreading your DAL, I don't see the issue.
FlySwat
@Jonathan, totally agree. The statement in the question about "warranting sequential access" is the one that made me think that this class is not bein gused in a multithreaded manner.
Rob Wells
+3  A: 

From "Design Patterns: Elements Of Reusable Object-Oriented Software":

It's important for some classes to ahve exactly one instance. Although there can be many printers in a system, there should only be one printer spooler. There should only be one file system and one window manager. ...

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
  • the sole instance should be extensible by subclassing and clients should be able to use an extended instance without modifying their code

Generally speaking, in web development, the only things that should actually implement Singleton pattern are in the web framework itself; all the code you write in your app (generally speaking) should assume concurrency, and rely on something like a database or session state to implement global (cross-user) behaviors.

Ian Varley
"the web framework itself should be a singleton" i'm not even convinced there's a benefit to that. if you only need one instance, just make one instance. no reason to add arbitrary constraints.
Dustin Getz
kinda like std::cout, which is a global instance w/ well known access point, but no reason to constrain to one instance.
Dustin Getz
A: 
  1. using a singleton here doesn't really give you anything, but limits flexibility
  2. you WANT concurrency or you won't scale
  3. worrying about connections and memory here is a premature optimization
Dustin Getz
+1  A: 

The Singleton pattern has lost a lot of its shine in recent years, mostly due to the rise of unit testing.

Singletons can make unit testing very difficult- if you can only ever create one instance, how can you write tests that require "fresh" instances of the object under test? If one test modifies that singleton in some way, any further tests against that same object aren't really starting with a clean slate.

Singletons are also problematic because they're effectively global variables. We had a threading issue a few weeks back at my office due to a Singleton global that was being modified from various threads; the developer was blinded by the use of a sanctioned "Pattern", not realizing that what he was really creating was a global variable.

Another problem is that it can be pathologically difficult to create true singletons in certain situations. In Java for example, it's possible to create multiple instances of your "singleton" if you do not properly implement the readResolve() method for Serializable classes.

Rather than creating a Singleton, consider providing a static factory method that returns an instance; this at least gives you the ability to change your mind down the road without breaking your API.

Josh Bloch has a good discussion of this in Effective Java.

Limbic System
A: 

with c#, I would say that a singleton is rarely appropriate. Most uses for a singleton are better resolved with a static class. Being mindful of thread safety is extremely important though with anything static. For database access, you probably don't want a single connection, as mentioned above. Your best bet is to create a connection, and use the built in pooling. You can create a static method that returns a fresh connection to reduce code, if you like. However an ORM pattern/framework may be better still.

In c# 3.5 extension methods may be more appropriate than a static class.

Tracker1
A: 

You have a repository layer that you want created once, and that reference used everywhere else.

If you go with a standard singleton, there is a bad side effect. You basically kill testability. All code is tightly couple to the singleton instance. Now you cannot test any code without hitting the database (which greatly complicates unit testing).

My advice, 1. Find an IOC that you like and integrate it into your application (StructureMap, Unity, Spring.Net, Castle Windsor...pick one). 2. Implement an interface for you repository.
3. Tell the IOC to treat the repository as a singleton, and to return it when code is asking for the repository by the interface. 4. Lean about dependency injection.

This is a lot of work for a simple question. But you will be better off.

Chris Brandsma
+1  A: 

As one example, object factories are very often good candidates to be singletons.

petr k.
+1  A: 

If a class has no state, there's no point in making it a singleton; all well-behaved languages will only create, at most, a single pointer to the vector table (or equivalent structure) for dispatching the methods.

If there is instance state that can vary among instances of the class, then a singleton pattern won't work; you need more than one instance.

It follows, then, by exhaustion, that the only cases in which Singleton should be used is when there is state that must be shared among all accessors, and only state that must be shared among all accessors.

There are several things that can lead to something like a singleton:

  • the Factory pattern: you construct and return an object, using some shared state.
  • Resource pools: you have a shared table of some limited resources, like database connections, that you must manage among a large group of users. (The bumpo version is where there is one DB connection held by a singleton.)
  • Concurrency control of an external resource; a semaphore is generally going to be a variant of singleton, because P/V operations must atomically modify a shared counter.
Charlie Martin