Wednesday, 10 March 2010

Factory Method - Why use it? What is it for?

The factory method is a creation pattern used in software engineering. Like a lot of patterns, it is sometimes hard to understand why to use it, since it involves a little more code and doesn't seem to provide a great benefit. Here is a real-world example and a software example.
Consider the Bank of England, they produce money and distribute it to other banks/people who can then spend it at which point it will eventually end up back at a bank. Now suppose that we all had to make our own money. We would need the tools but even if it was easy, what would happen if the bank wanted to change a coin or introduce a new one? Everyone who produced coin would have to get the new tooling/instructions and this would be a headache. It would be hard and some people might carry on making the old coins and would only have a problem when they were spent. We don't do that. Money both originates from and ends up back at the banks. It is a factory method. If the bank wants to change a coin, it changes it and the new ones appear automatically. In this case old coins take time to be used up but it is relatively easy to do.
Now consider a software problem. A classic: database access. I want to call a function that calls a database function with parameters, how do I do this? The most trivial way is this:

DataAccess.CallFunction("nameOfMyProc", new SqlParameter("@Name", Value));

What is the problem with this? It assumes that we are using MS Sql Server and this will never change. It assumes that the SqlParameter constructor takes exactly 2 parameters and possibly these are valid assumptions but do not promote either re-use in other systems that might not use Sql Server and does not allow for using a different database without loads of code changes. If the SqlParameter constructor changed which is not unheard of, everything breaks. A little effort now and the factory pattern can give us the same functionality with none of these problems. We create a function in our data access class called CreateParameter and this can return an abstract base class of parameter (in my case DbParameter) so consider:

DataAccess.CallFunction("nameOfMyProc", DataAccess.CreateParam("@Name", Value));

Nothing here assumes Sql Server usage; if the 'shape' of the SqlParameter which we are actually returning from the CreateParam function changes, we can possibly keep this change hidden inside the data access layer (depending on what the new argument might be) and we can literally unplug a Sql Server layer and plugin e.g. a MySql layer instead with NO code changes outside of the DataAccess.
A lot of people would say, "we will always use Sql Server, it's not an issue" but there are many reasons why you might want or need to change in the future. Imagine someone releases a free and fully compatible database that gets rave reviews - save a few quid! Imagine for some reason that you have new database servers which are not compatible with Sql Server. Imagine you get bought out by a larger company who insists you use MySql. It would look really professional if you simply wrote another data layer and knew that it would all work!
Post a Comment