Introduction
In the first article of this series, we talked about one of the basic Design Patterns called “Singleton” which can be used to solve a lot of problems effectively. Here we are going to talk about another popular Design Pattern called “Abstract Factory”.
Abstract Factory
Consider you want to build a program with different themes (for example XP and Vista theme). Each theme consists of some different widgets like window, button, checkbox, etc. When you select a theme, you want every widget that you create to follow that theme. A quick solution is to declare a global variable indicating the current theme and using switch/case everywhere you create a widget:
#define XP_THEME 1
#define VISTA_THEME 2
extern int g_SelectedTheme;
switch(g_SelectedTheme)
{
case XP_THEME:
window = new XPWindow();
break;
case VISTA_THEME:
window = new VistaWindow();
break;
}
When your code goes larger and you want to build multiple widgets in different parts of the code, creating new widgets turns to a nightmare.
This is where the story of the Abstract Factory begins. To solve the problem using this method, we need to create four types of classes:
- Abstract Factory (
ITheme)
- Actual Factory (
VistaTheme, XPTheme)
- Abstract Product (
IWindow, IButton)
- Actual Product (
VistaWindow, XPWindow, VistaButton, XPButton)
Here is how it looks like:
class IWindow
{
};
class IButton
{
};
class ITheme
{
public:
virtual IWindow *CreateWindow() = 0;
virtual IButton *CreateButton() = 0;
};
class XPWindow : public IWindow
{
};
class XPButton : public IButton
{
};
class XPTheme : public ITheme
{
IWindow *CreateWindow()
{
return new XPWindow();
}
IButton *CreateButton()
{
return new XPButton();
}
};
class VistaWindow : public IWindow
{
};
class VistaButton : public IButton
{
};
class VistaTheme : public ITheme
{
IWindow *CreateWindow()
{
return new VistaWindow();
}
IButton *CreateButton()
{
return new VistaButton();
}
};
And here is how you can use it:
ITheme *theme = NULL;
theme = new VistaTheme();
theme->CreateWindow();
theme->CreateButton();
Well, it looks much better. A good idea is to define Theme classes as Singleton because you don’t need to instantiate more than one theme at a time. OK, there are a lot of other implementations of Abstract Factory, just choose one that fits your needs. If you have comments or questions, let me know by writing to vkazemi {at} gmail.com and make sure to check my web site for updates: http://www.gameprogrammer.org.
Good luck!
History
- 4th September, 2006: Initial post