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 t开发者_JAVA技巧he 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
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.
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.
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...
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.
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.
Singleton 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 functionality 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.
精彩评论