views:

234

answers:

6

Hello Everyone

There are already quite some posts about the Singleton-Pattern around, but I would like to start another one on this topic since I would like to know if the Factory-Pattern would be the right approach to remove this "anti-pattern".

In the past I used the singleton quite a lot, also did my fellow collegues since it is so easy to use. For example, the Eclipse IDE or better its workbench-model makes heavy usage of singletons as well. It was due to some posts about E4 (the next big Eclipse version) that made me start to rethink the singleton.

The bottom line was that due to this singletons the dependecies in Eclipse 3.x are tightly coupled.

Lets assume I want to get rid of all singletons completely and instead use factories.
My thoughts were as follows:

  • hide complexity
  • less coupling
  • I have control over how many instances are created (just store the reference I a private field of the factory)
  • mock the factory for testing (with Dependency Injection) when it is behind an interface
  • In some cases the factories can make more than one singleton obsolete (depending on business logic/component composition)

Does this make sense? If not, please give good reasons for why you think so. An alternative solution is also appreciated.

Thanks

Marc

+3  A: 

I agree that it makes senses sometimes. However, it depends on what you're building.

If you replace every single singleton with a factory just because its "better", you're doing it wrong imho. It should serve a purpose. If you're not going to mock, if you're sure you only need one instance, etc than replacing is just "architectural mastrubation" ;)

Dont get me wrong, architecture is very important, but you shouldn't overdo it.

Henri
Since there are 3 answers with 2 upvotes, it was difficult to choose which one is best. I decided to mark this one as the correct one due to the warning about overdoing patterns just for architectural reasons
lostiniceland
+1  A: 

Singletons as described in the design pattern usually use static variables which makes code hard to test.

I would recommend reading this from Miško Hevery and the two follow up articles 1 and 2. Here he describes what the difference between an object with a single instance and a Singleton object like in the design pattern is and that the first one should be preferred.

So your described approach would be the way to go in my opinion.

MKroehnert
Thanks for the link. I actualy came accross this post some time ago but then I lost the link (I only remembered the first points).
lostiniceland
+2  A: 

In my understanding you cannot "replace" a Singleton with a Factory but you could use these patterns together. A Factory will return an instance of an object to the caller of the Factory method. If you want to make sure there is only one instance of a particular object that the Factory returns, then that object should be a Singleton. You are hiding the Singleton in the Factory.

If you are storing the private instance of the object in the Factory rather than in the object itself - then how can you enforce that there is only ever one instance of the object in the system? How can you enforce that that object will only ever be created by your Factory?

You can replace a Singleton with IoC alright and indeed there does seem to be a lot of bad feeling towards the Singleton as an anti-pattern and even Gamma said he wished he had left it out of the GoF book...

Peter Kelly
Good points. Regarding your points how to make sure there is only one instance of a class when I put a private instance in my Facroty: I would make the object "package private" so only the Factory in that package can call it. Of course this only works for closed source. In a development team I would document it propertly but you're right..technically it is not ensured that there is only one instance. But so it is when you are using the singleton-pattern in an OSGi-environment since each bundle has its own classloader (just to mention this)
lostiniceland
Interesting point about the OSGi-environment - I hadn't thought about that.
Peter Kelly
Just on reading up on that I found a couple of links that might be interesting http://tech.jayasoma.org/2008/12/how-to-make-your-osgi-bundle-singleton.htmlhttp://stackoverflow.com/questions/1318856/migration-solution-for-singletons-in-an-osgi-environment
Peter Kelly
But his only makes the bundle a singleton. In OSGi you can have multiple bundles of the same type running at the same time. The singleton directive just avoids this. To get one classloader for multiple bundles you can use the "buddy-policy". I had to use this once for hibernate. But this is more like a workaround when using a framework that is not provided as a bundle and not intended to fix some singleton-pattern classloading issues :-)
lostiniceland
+2  A: 

Factory is definitely an alternative to Singleton, and I would prefer the former over the latter. Singletons are very difficult to test and lead to tight coupling. Factories, if correctly implemented (using pure interfaces, etc.), leads to more testable code and less coupling.

That said, this doesn't mean you should use Factories as a sledgehammer for every problem. There are other patterns that can also lead to less coupling than Singleton but be a more appropriate solution. For example: Inversion of Control.

jkohlhepp
Personally, I find the ServiceLocator pattern much more ammenable to substitution for Singleton than Factory is. Martin Fowler discusses this topic: http://martinfowler.com/articles/injection.html#UsingAServiceLocator
LBushkin
+2  A: 

In my eyes, the major disadvantage of singletons is tight coupling (with all its consequences like crappy testing, etc).

The factory pattern allows a much more loose degree of coupling, so yes: replacing singletons with factories sounds like a good idea.

As Peter Kelly mentions, factories can sometimes also end up being singletons. However, factories at least don't return an instance of themselves, but rather an instance of some interface implementation, and this is a huge plus.

Eric Eijkelenboom
+1  A: 

Sigleton is an antipattern of course. And if you're using TDD - you should avoid such solutions. Any IoC Framework such as Windsor or Unity can emulate this fucntionality for you without terrible static classes. However if you are not using TDD and your project is pretty simple you can use it. Btw I'd recommend IoC Framework over self-made factories. Don't invent a wheel.

Voice
Yes, I am trying to use TDD as much as possible but still I try to keep the amount that is put together by IoC at an moderate rate (component composition). The Spring advocates always state that you write so little code with it but they forget to mention the huge xml files :-)
lostiniceland
Well, I can say that Spring is not the best IoC solution for .NET. It is powerful but not user-friendly. Especially due to its horrible config. Try Windsor or Unity - much better)
Voice