Factory Refactored
Although the orthodox Factory pattern uses string comparisons to determine the actual derived object, there is a cleaner and more efficient way to achieve the same results. Replacing the string argument of create() with an enumeration will produce significantly faster code and enable you to use a switch which is more readable and easier to maintain than a list of else-ifstatements.
First, add an enumeration into the Image Factory class:
class ImageFactory
{
public:
enum ImgFormat
{
JPG,
BMP,
//...add new image formats as necessary
DEFAULT
};
};
Next, add a switch block to create():
static Image* create(ImgFormat fmt)
{
switch (fmt)
{
case JPG:
return new JpegImage;
break;
case BMP:
return new BmpImage;
break;
default:
return new PngImage;
}
}
Finally, change main()accordingly:
int main()
{
ImageFactory factory;
auto_ptr<const Image> img(factory.create(ImgFactory::JPG));
img->image_type();
img.reset(factory.create(ImageFactory::BMP));
img->image_type();
img.reset(factory.create(ImageFactory::DEFAULT));
img->image_type();
}
A Timeless Solution
Recently, I've seen several questions in the C++ forumregarding techniques for creating derived objects at runtime. In all these cases, Factory has proved to be the right solution. This only goes to show that classic design patterns are still as relevant as ever.