views:

1988

answers:

12

We have a class that holds configuration information for the application. It used to be a singleton. After some architectural review, we were told to remove the singleton. We did see some benefits of not using singleton in the unit testing because we can test different configurations all at once.

Without singleton, we have to pass the instance around everywhere in our code. It's getting so messy so we wrote a singleton wrapper. Now we are porting the same code to PHP and .NET, I am wondering if there is a better pattern we can use for the configuration object.

A: 

Is a class that contains only static methods and fields possible? I'm not sure of exactly what your situation is, but it might be worth looking into.

Thomas Owens
If the class is stateless, it should be a static class.
AlbertoPL
It is in C++ - the pattern is known as a Monostate.
anon
+5  A: 

The best way is to use a Factory pattern instead. When you construct a new instance of your class (in the factory) you can insert the 'global' data into the newly constructed object, either as a reference to a single instance (which you store in the factory class) or by copying the relevant data into the new object.

All your objects will then contain the data that used to live in the singleton. I don't think there's much of a difference overall, but it can make your code easier to read.

gbjbaanb
I don't agree with the "best way" statement, but +1 for a good alternative.
tylermac
+5  A: 

I might be stating the obvious here, but is there a reason why you can't use a dependency-injection framework such as Spring or Guice? (I believe Spring also is available for .NET as well now).

That way, the framework can hold a single copy of the configuration objects, and your beans (services, DAOs, whatever) don't have to worry about looking it up.

This is the approach I usually take!

Phill Sacre
A: 
__roland__
+2  A: 

If you use Spring Framework, you can just create a regular bean. By default (or if you explicitly set scope="singleton") only one instance of the bean is created and that instance is returned every time the bean is used in a dependency or retrieved via getBean().

You get the advantage of the single instance, without the coupling of the Singleton pattern.

CoverosGene
+35  A: 

The Google Testing blog has a series of entries about avoiding Singleton (in order to create testable code). Maybe this can help you:

The last article explains in detail how to move the creation of new objects into a factory, so you can avoid using singletons. Worth reading for sure.

In short we move all of the new operators to a factory.
We group all of the objects of similar lifetime into a single factory.
FrankS
Google testing blog is required reading.
koen
*** Using dependancy injection to avoid singletons
Justin
Thanks, didn't notice the typo
FrankS
These articles are as good as the Google C++ Programming Standards!
anon
Well, not really. The 'Do not use static methods' advice goes straight against Scott Meyers / Herb Sutters' minimal interface principle for example. There are useful advice, but they lack the contribution of multiple minds.
Matthieu M.
A: 

Depends on what tooling/frameworks etc.. are being used. With dependency injection/ioc tools one can often still get singleton performance/optimizations by having the di/ioc container use singleton behaviour for the class required - (such as a IConfigSettings interface) by only ever creating one instance of the class. This could be still substituted out for testing

Alternately one could use a factory to create the class and return the same instance each time you request it - but for testing it could return a stubbed/mocked version

saret
+2  A: 

The alternative is passing in what you need instead of asking an object for things.

koen
A: 

Review possibility to make configuration as callback interface. So your configuration sensitive code will look:

MyReuseCode.Configure(IConfiguration)

System-init code will look:

Library.init(MyIConfigurationImpl)
Dewfy
+3  A: 

don't accumulate responsibilites to a single configuration object since it will ends in a very big object that is both difficult to understand and fragile.

For example if you need another parameter to a particular class you change the Configuration object, then recompile all the classes that uses it. This is somewhat problematic.

Try refactoring your code to avoid a common, global and big Configuration object. Pass only required parameters to client classes:

class Server {

    int port;

    Server(Configuration config) {
        this.port = config.getServerPort();
    } 

}

should be refactored to:

 class Server {

    public Server(int port) {
       this.port = port;
    }
 }

a dependency injection framework will help a lot here, but it isn't stricly required.

dfa
Yes it's really good point. I have done this before. My big configuration object was implementing interfaces like MailServiceConf, ServerConf.. than Dependency Injection framework passes configuration to classes so my classes was not dependent on big Configuration object.
mcaaltuntas
A: 

You could use a dependency injection framework to ease the pain of passing in the configuration object. A decent one is ninject which has the advantage of using code rather than xml.

Colin Gravill
A: 

You can accomplish the same behavior of singleton by using static methods. Steve yegge explains it very well in this post.

Youssef
Actually the article is quite good, and it does not say you should use static methods instead. Instead he states that static methods are just singletons as well and at the end he recommends using the factory method pattern:"I'll close by saying that if you still feel the need to use Singleton objects, consider using the Factory Method pattern instead. ..."
FrankS