31

I am making a database to store information about the users of my website (I am using stuts2 and hence Java EE technology). For the database I'll be making a DBManager. Should I apply singleton pattern here or rather make all its methods static?

I will be using this DBManager for basic things like adding, deleting and updating User profiles. Also, I'll use it for all other querying purposes, for instance to find out whether a username already exists and to get all users for administrative purposes and stuff like that.

My questions:

  • What is the benefit of singleton pattern?
  • Which thing is most apt here? All static methods or a singleton pattern?
  • Please compare both of them.

P.S. The database is bigger than this. Here I am talking only about the tables which I'll be using for storing User Information.

1

5 Answers 5

20

Why are Singleton and static method your only options?

From my point of view, both options are pretty bad. Read up on the Singleton AntiPattern. Most use cases of the Singleton Pattern is incorrect.

In your case, I would use an instance object and use dependency injection (if you're using a DI framework) or a Service locator/Registry pattern

3
  • 10
    The question is what is the difference between singleton and static, not why am I not using depdendency injection.
    – Zombies
    Commented Mar 10, 2013 at 13:34
  • The question is actually a bad 2 in 1. But I agree with @Zombies - the broader question should be addressed first. Also, I think Toolbox is better than Service locator.
    – cregox
    Commented Nov 13, 2013 at 20:11
  • To anyone coming here in The Future™ like me, here's a more useful answer: softwareengineering.stackexchange.com/a/235528/104052
    – Ky -
    Commented Jan 18, 2023 at 22:02
17

With a singleton class, you have more control in terms of how you manage the object that is created.

First, a singleton is an object. The static method returns an instance of the object and allows you to create only a single instance, or more if you so choose.

Singletons are also lazy-loaded, meaning that they are not instantiated until the first time they are called.

A singleton doesn't use static methods, so you won't have trouble using it in a non-static context.

Singletons can be extended/subclassed.

Since they're objects, they can be injected into other objects, which allow for the creation of some great design patterns utilizing the concepts of dependency injection. For example, this is how the Spring Bean IoC (Inversion of Control Dependency Injection) model works.

4
  • 3
    +1. Also, singletons can implement interfaces.
    – Kramii
    Commented Jan 7, 2011 at 11:50
  • Huh, what?! Singleton is an object? Static method returns an instance? You seem to be more confused than I was when learning about those things... They're also not necessarily lazy-loaded and it sure can use static methods. I'm also not so sure you should extend a singleton, but sure, I think you could.
    – cregox
    Commented Nov 13, 2013 at 16:04
  • 3
    @Cawas Yes, a singleton is a specific type of object. You generally retrieve it by using a static method on the class, which manages whether to return the existing instance or create it.
    – Izkata
    Commented Nov 14, 2013 at 5:22
  • 1
    @Izkata oh I see now what he meant. Thanks. The first sentence is actually ok now. I first was reading a "singleton is an object" versus static methods returns an instance". Maybe it could be rephrased less ambiguously, but who am I to judge that? I do such stuff all the time.
    – cregox
    Commented Nov 14, 2013 at 10:43
3

What is the difference between all-static-methods and applying a singleton pattern?

Both have the same effect: you can call a class method without careing how to get an instance of the class that contains the method.

However if you want to implement Unittesting static methods are more problematic because they can not be easily mocked.

From the testing perspective it is easier to rewite code that uses singeltons to make them unittestable with mocks.

The most flexible soulution would be to have Dependency_injection no matter if you are using a di-container-framework (as suggested by @Tazzy531 ) or if you are wireing dependencies by code.

3

Neither is ideal, but especially not a bunch of statics. Here's a real world example from my experience. We talked to a database. Everybody said "there will only be one", so somebody used a standard singleton configured by Spring. Then there was a new requirement added: to be able to copy our data to another (remote) database. Oops. Since we had an actual Object representing the DB, and this was a "rarely used" feature, I was able to hack it by making a temp copy and changing fields and values, but had this been implemented with global statics it would have been a real disaster.

In my experience, when "they" say that there will be only one DB, one user, one application, one main window, etc., "they" are wrong. With a Singlton you at least have a chance to refactor and fix it.

2

I hope this will answer just the main question here.

There are already few great answers in SO. I'll just quote them.

Best answer, by Heinzi:

A singleton is used to introduce some kind of global state to an application. If it is stateless, I also don't see the point of using a singleton, unless

  • you expect to extend it with state in the foreseeable future or
  • you need an object instance for some particular technical reason (for example, for the C# SyncLock statement, although this is already quite far-fetched) or
  • you need inheritance, i.e., you want to be able to easily replace your singleton with another one using the same interface but a different implementation. For example, the Toolkit.getDefaultToolkit() method in Java will return a singleton whose exact type is system dependent.

High relevant comment, by back2dos:

(...) singletons are misused to introduce global states. The purpose of a singleton is not to make an object globally available, but to enforce that an object is instantiated only once. Global objects are a necessary evil. Unless really required, one should try not to use them, since they generally lead to high coupling, with SomeSingleton.getInstance().someMethod() all over the place.

tzaman also wrote a good answer:

I could see a case for a stateless singleton being used instead of a static methods class, namely for Dependency Injection.

If you have a helper class of utility functions that you're using directly, it creates a hidden dependency; you have no control over who can use it, or where. Injecting that same helper class via a stateless singleton instance lets you control where and how it's being used, and replace it / mock it / etc. when you need to.

Making it a singleton instance simply ensures that you're not allocating any more objects of the type than necessary (since you only ever need one).

And finally Sebastien also answered himself quite well:

Actually i've found another answer not mentionned here: static methods are harder to test.

It seems most test frameworks work great for mocking instance methods but many of them no not handle in a decent way the mock of static methods.

That being said, I advise using the Toolbox pattern.

2
  • 1
    Making the singleton built like a COM object doesn't make it any less offensive... quite the opposite. Dredging up old threads to answer with other old answers does not contribute to the site.
    – Telastyn
    Commented Nov 13, 2013 at 20:30
  • @Telastyn I only came to answer because I thought the 3 current ones were really poor, while that other "topic" had much more relevant info. From where I stand. The second part of your comment is what's not contributing at all. And this is not a COM object. It's more like a singleton service locator (rather than a static one). But I was actually reluctant of simply quoting the other answers and if you tell me stackoverflow site is hosted in the same place as this, I might completely edit this again.
    – cregox
    Commented Nov 13, 2013 at 20:36

Not the answer you're looking for? Browse other questions tagged or ask your own question.