Posts Tagged ‘ Singleton Pattern

Singletons And Dependency Injection

That global variables are a bad thing is so deeply ingrained into programmers many have never looked into why this is. It should come as no surprise that these same engineers latch onto the singleton pattern and abuse it in the same way many 10 year olds used global variables on their ZX81s.

One of the many reasons why global variables are bad is that you do not know where they are being used. We try our hardest to write code that is clean and explicit. Global variables are anathema to this pursuit. The singleton pattern gets used in much the same way Рtypically for an application registry or a database connection.

We have a project, for example, that uses the singleton pattern as a database connector. The project is quite tidy with database access being limited to a selection of data mapper classes. Recently, however, we needed to add a second database connection – it took much more effort than anticipated to identify where the database is being used whilst ensuring the singletons didn’t cross over.

A better way of approaching database connections is to pass a connection, instantiated as an object, to the object that needs it as the object is being constructed. This is clearly identifies wherever the object is used which database connections are being used. Adding a second connection becomes a trivial exercise. This technique of passing in an object to another is known as dependency injection.

The killer application, though, is unit testing. Using dependency injection means that when you create your test cases you can use a completely different database connection, or even a test stub, rather than the connection defined in the registry. This makes it really easy to test, completely and accurately, a complex class that relies on a database connection. I’ve been coding long enough to be completely in favour of “really easy”.

Better yet, is test first development, it means you can write and test your class before the database has even been set up.