The factory pattern can be summed up pretty easily by its name, a factory. If we think about a factory in the real world it makes things. A factory won’t make cars and sweets in the same factory, it makes the same items of the same type. A Mercedes Benz factory will make all the different types of Mercedes Benz, a sweet factory will make all different types of sweets and so on. So it is the same with the factory pattern, you have a factory that builds items of the same type. Below is a car factory, it is very simple and does not achieve a great deal but this will demonstrate how a standard factory works.
/* * This is our base class for the factory, this will hold * general methods accessable to all the difference cars. */ class car { protected $engineSize; protected $color; /* * just some random access methods to return the various * different properties */ function getEngineSize() { return $this->engineSize; } function getColor() { return $this->color; } } /* * This is a new class for one of the cars, for a factory * you each item that will be made by the factory will need * its own class. This is what makes it a factory. */ class gallardo extends car { protected $engineSize = '5000cc'; protected $color = 'red'; } class phantom extends car { protected $engineSize = '6500cc'; protected $color = 'black'; } /* * This is the factory. This is where the magic happens. You can * think of all the classes above as blue prints and the factory * will make each item according to its blue print. Provided they * are part of the base class we can use them. */ class carFactory { const FACTORY_BASE = 'car'; public static function createCar($type) { $base_class = self::FACTORY_BASE; /* * What we are checking here is that this item is allowed * to be made by the factory. In order to be made by this * factory, the parent class, in this case car needs to * exist and we also need to make sure that the type we * specify is actually a sub class of this. If either of * these fail, we must not continue. */ if (class_exists($type) && is_subclass_of($type, $base_class )) { return new $type; } else { throw new Exception("{$type} is not an instance of {$base_class}"); } } } /* * This is very basic sample usage of the basic factory class. */ $newCar = carFactory::createCar('phantom'); var_dump($newCar->getColor()); var_dump($newCar->getEngineSize());
Where would we use this in our code? Well, an example would be in reporting. A report can be in various different formats and we could use a factory to build these reports. In doing this we can add the types, pdfReport(), csvReport() or even standardOutputReport(). In doing this we can build our code for reporting and if we need to expand on our reporting output, we can just add a new blue print for a new report and have the factory make it.
I hope this gives you a better understanding of the basic factory pattern, as always, feel free to leave your comments.
Very cool. I learned the command pattern a long time ago, and I eventually started using it for this exact same reason. I just didn’t know this is what the factory pattern was, but I guess I’d been using it for a while now. I like how this completely eliminates the need for those ugly conditional statements that you see so often in these patterns. Through proper use of OO, there is no need to use Ifs to check state. Nicely done…