12

I am developing a RESTful API and I think it is convenient to use DAOs for my resources because although I plan on just using memory to store them, I don't want to close a door to whoever is using my library if they decided to use a database implementation for the DAO.

My question is whether the DAO should be a singleton or not. If it is not, the service will have an instance of the DAO and it would look roughly like this:

@Path("eventscheduler")
public class EventSchedulerService {
    private IEventSchedulerDao dao = new EventSchedulerDao();

    // in case a different implementation is to be used
    public void setEventSchedulerDao(IEventSchedulerDao dao) {
        this.dao = dao;
    }

    @Path("{uniqueName}")
    @GET
    @Produces(MediaType.APPLICATION_JSON)
    public Tournament getTournament(@PathParam("name") String uniqueName) {
        return dao.get(uniqueName);
    }

    @Path("create")
    @POST
    @Consumes(MediaType.APPLICATION_JSON)
    @Produces(MediaType.APPLICATION_JSON)
    public Tournament createTournament(Tournament tournament) {
        return dao.create(tournament);
    }
}

While if the DAO was a singleton, but I guess there wouldn't be much of a difference, just in the first line:

private IEventSchedulerDao dao = EventSchedulerDao.getInstance();

I would still have to use an IEventSchedulerDao instance, but I guess all singletons work like this right? For some reason I always correlate singletons to static methods, so instead of having a singleton instance visible to the user with getInstance(), this would be hidden and he/she would just use EventSchedulerDao.get(name), etc... in a static fashion. Is this a thing or is this just me?

So, should I or should I not have singleton DAOs?

And as a side question, is it alright my approach to have open doors for the user to implement their own DAOs?

  • You could use an IoC singleton instead of a singleton with a static accessor. – CodesInChaos Jun 3 '16 at 12:08
11

I wouldn't use a singleton. It's a recognised anti-pattern, and makes testing difficult. I would much rather inject in a concrete implementation, and have your service reference a DAO interface (allowing you to inject different implementations in)

  • 1
    What you suggest in your last sentence is precisely what I am doing right? – dabadaba Jun 3 '16 at 11:00
  • 1
    You're referencing via an interface (yes), but you're not injecting the DAO (to be clear....) – Brian Agnew Jun 3 '16 at 11:01
  • What do you mean? I have a setter for it, don't I? – dabadaba Jun 3 '16 at 11:03
  • @dabadaba The line private IEventSchedulerDao dao = new EventSchedulerDao(); is where you've gone wrong. The implementation for IEventSchedulerDao should be injected via the constructor and never changed (ie, get rid of setEventSchedulerDao too). – David Arno Jun 3 '16 at 11:04
  • Okay, I understand. I just did that to provide a default DAO and changing it would be "optional". But taking your suggestion means having a constructor for the service different than the default, and honesly I have no idea how that works out with Jersey because it uses the default constructor. By any chance do you know how to do that? – dabadaba Jun 3 '16 at 11:10
2

A Data Access Object should only really exist once in your application. The logic remains the same, the only things that are different are the values coming in and out of the methods the DAO provides.

With that in mind, obviously the first thing that usually happens is implementing the DAO as a strong singleton, that is when you have a static method on a factory class, something like getInstance, lazy loading an instance of the DAO if it's null and returning it.

Excuse me if the syntax is not completely right, I'm not a Java programmer.

class DaoSingletonFactory
{
    private static Dao dao = null;

    public static Dao getInstance()
    {
        if (DaoSingletonFactory.dao == null) {
            DaoSingletonFactory.dao = new Dao();
        }

        return DaoSingletonFactory.dao;
    }
}

class UsesDao
{
    public void someMethod()
    {
        Dao dao = DaoSingletonFactory.getInstance();
    }
}

This is incredibly hard to test, because you cannot swap out the implementation without altering the code of the UsesDao class. That can be done through some monkey patching, but is not generally considered a good practice.

Then there is the better way, the weak singleton pattern, where you don't retrieve an instance through a static method, but make all classes depend on the instance either through a constructor or a setter (in your EventSchedulerService you are using the setter injection).

The only problem is, you then need to make sure that all the classes, which depend on an instance of class which should only exist once your application life cycle, are taking the same instance as their parameter, ie. the new is called only once on the DAO object in the entire application.

Obviously, this is incredibly difficult to track and constructing the object-graph is a tedious and annoying work.

Luckily, there are IoC containers, which make it much easier. Besides Spring, the Guice IoC container by Google is quite popular among Java programmers.

When using an IoC container, you configure it to behave in a certain way, ie. you tell if how it is supposed to construct certain classes and if some class is required as a dependency, how the dependency should look (whether it should always be a new instance or a singleton) and the container wires it all up.

You can check this link for a singleton example with Guice.


Pros and cons of using an IoC container

Pros

  • saving budget by not having to write all factory methods yourself
  • (usually) very straightforward configuration
  • quick development

Cons

  • a wizard's magic, the classes are somehow constructed and you can't really see how it happened
  • a little performance drop due to class lookup (manually written factories will be slightly faster)
1

Singleton is refering to the concept just only one instance and the way to get access to the instance (through the so famous static method getInstance())

But there's still an instance behind all of that. A built object with a sort of resticted access.

In your case, I would rather go for DI approach (dependency injection). Like the first block of code you have exposed. Just a little change. Inject the DAO via constructor. To remove or not the setter is up to you. If you want to protect Controller from changes in runtime then remove it. If you want to offer such possibility, then keep it.

You are right on using an Interface and offering a open window for further DAO's implementations. May or may not be needed. It takes just one minute more of work, but it turns your design flexible. Your in memory DAO is quite common. Very usefull as mock at testing time. Or as default DAO implementation.

Just a hint. Static resources (objects, methods, constants or variables) are like global resources. If globals are evil or not is matter of needs or tastes. However there're implicit shortcomings bound to them. These are related to concurrency, thread-safety (in Java, don't know about other languages), serialization...

So I would suggest to use statics cautiously

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

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