Monday, February 20, 2006

Design Patterns: Factory Pattern

I have always heard of the factory pattern and it is one of the more common patterns out there. I just never really knew why / when to use it until recently. There are serveral compelling reasons to use the factory pattern.

What is a factory?
Simply put factories are classes / methods that build objects. Here is a simple example of a factory that creates a car:

public function CreateCar(color as string, model as string, year as integer, isHatchback as boolean) as Vehicle
dim car as new Vehicle()
car.color=color
car.model=model
car.year=year

if isHatchback then
car.NumberOfDoors = 3
else
car.NumberOfDoors = 4
end if

return car
end function

we could then add another factory that creates a truck

public function CreateTruck(color as string, model as string, year as integer) as Vehicle
dim truck as new Vehicle()
truck.color=color
truck.model=model
truck.year=year
truck.numberOfDoors = 2
return truck
end function



What I like to do is put the factory methods directly into the object I am creating (in this case Vehicle). I then make the constructor private to force users to call the Create____ method. i.e.:

public class Vehicle()
dim color as string
dim model as string
dim year as integer
dim numberOfDoors as integer
dim fuel as string

private sub new()
engine = "gas"
end sub

public shared function CreateCar(color as string, model as string, year as integer, isHatchback as boolean) as Vehicle
dim car as new Vehicle()
car.color=color
car.model=model
car.year=year

if isHatchback then
car.NumberOfDoors = 3
else
car.NumberOfDoors = 4
end if

return car
end function

public shared function CreateTruck(color as string, model as string, year as integer) as Vehicle
dim truck as new Vehicle()
truck.color=color
truck.model=model
truck.year=year
truck.numberOfDoors = 2
return truck
end function

end class

Now if you are anything like me you would be thinking why not just use the new constructor in vehicle to do this? The answer is yes we could but no we should not.

The main reason I use a factory is clarity. You can only name a constructor "new". which is not very descriptive. If we used the new constructor the signature woud look like this:
public sub new (color as string, model as string, year as integer, isHatchback as boolean)
public sub new (color as string, model as string, year as integer)

As a developer not familiar with the code I might assume I can create a car by calling the second method only to be supprised that it comes back as a car with 2 doors which is not what I desired. Where as if it was done through the factory method I know just by the name of the method that I should call CreateCar() to create a car and CreateTruck() to create a truck.

The other place a factory can be usefull is with inheritance chains as the new() constructors on objects do not get inherited but the factory methods will.

It is quick to see how powerfull this technique can be and where it can be used. Be warned though that most developers expect methods to have a new constructor on objects. This is why it is gennerally a common practice to prefix factory methods with the word Create. i.e. sqlConnection.CreateCommand() returns a command object associated to the command.

0 Comments:

Post a Comment

<< Home