Thursday, December 06, 2007

Factory Methods over Constructors

There is a lot of talk about how singles are harmful. Many of them make very good points. However, I think one thing that is generally missing from the discussion is a small pattern that is almost universally used when implementing singletons.

I mean of course, the factory pattern.

Very few people provide public access to singleton variables, they are usually provided via an instance() method. The class is its own factory object.

Why is this good?

It means you don't have to use singletons, though they could be an option. Say a class needs to operate on a non-thread safe class (an xml transformer for example), or it uses a library of uncertain thread safety. Instead of having a static reference to the instance that is returned by the factory method, it could use a ThreadLocal to ensure that each thread has its own instance. This gives the ability top address issues with threads while gaining the benefits of a singleton.

Another use of the factory pattern can be object pooling. If the object is pretty heavy weight, or requires a lot of set-up, you obviously don't want to have too many instances floating around or don't want to create them too frequently. You could write your own pooling implementation or use the Jakarta Commons Pool.

If a singleton is the right thing to do, then it should obviously be used. Consumers of the class should not have to worry about whether or not it is a singleton. Of course, this also means you shouldn't be storing state information in the class (but, you knew that).

What does this mean for testing? A private constructor is still going to prevent over-riding the class to create "truly" new instances. This means another option will have to be taken.
Perhaps the easiest is to over-load the factory method with one that always returns a new object. If the scope of this method is limited to package level, then little more than the test case should have access. The problem here is, an overly cautious developer may discover the method and use it instead of the factory class.

I would propose testing the class the same as it will be used. If there is a concern about internal state, write tests to cover it. Besides, maintaining internal state in class provided by factory methods is generally a bad practice. Try writing tests to ensure this isn't happening.

Another option could be to refactor so that a separate factory object is used, and it could be over-ridden to provide a class for testing...

Though there are problems with singletons, don't throw out the baby with the bath water. The nature of a good singleton makes it easy to do things beside a single instance in a very transparent way.

Labels: , , , , ,

permalink
Links to this post

1 Comments:

At 07 December, 2007 17:18, Blogger klimek said...

The problem I see with singletons is not that they provide a factory method, which is a nice thing, but that they
- restrict developers to use only one instance of a class, whatever reason they may have to do this in the future
- make it look like using global data is a good thing, which it is not.

The second point is important. When Singletons are introduced what I've seen much too often is that the singleton factory method was then used everywhere, coupling the singleton factory method to the weirdest places in the code base.

If I have to make sure everybody understands how not to use a factory method, I can skip the whole fuzz of making a singleton truly single, and could even use non-static factory methods.

Cheers,
Manuel

 

Post a Comment

Subscribe to Post Comments [Atom]

<< Home

Links to this post on:

Create link here by posting on Blogger