I used to loath the singleton pattern, mostly because of the pain it has caused me whenever I take over some old code and try to write test on it. Interesting enough, Guidewire has used it in a way that is actually kind of cool.
If you have tried to manage component dependencies before the IoC container came out, you are probably fully aware of the pain you have to go through when a new dependency is introduced. Either you end up with a HUGE interface, or you have to change the signature of a handful classes and make some of them have longer parameter list in the process.
Here those dependencies are manager as "Dependencies" singleton interface. It is a set of static methods to be precise. So if a class decides it needs to use metadata layer to build the query and database layer to execute the query (like the archiving project that I am working on), it can just grab the instance by calling "PLDependencies.getExtractController()" and "DatabaseDependencies.getDatabase()". The dependencies are set up during the server initialization (through dependency registrations) and never changes.
There are some behavior changes associated with this design. Two on top of my head:
* No mocking/stubbing. Nothing is stubbed out within the application. We use H2 for testing and the database is reset using restore. So the tests run fairly fast. After seeing some horrible mocking code, I like this style more and more.
* Be aware of the dependencies. With dependency injection, you get used to understanding the dependency relationships by looking at the construction and method parameter list. With this design, surprises can really happen. You could very well call into something that does not take any parameter only to find out that it actually does a lot of things.
It is not the perfect design, but once you understand the pattern and learn not to abuse it, you can actually manage the dependencies quiet easily.