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, and 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 every where 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:
/*
* Abstract Theme
*/
class IWindow
{
//...
};
class IButton
{
//...
};
class ITheme
{
public:
virtual IWindow *CreateWindow() = 0;
virtual IButton *CreateButton() = 0;
};
/*
* XP Theme
*/
class XPWindow : public IWindow
{
//...
};
class XPButton : public IButton
{
//...
};
class XPTheme : public ITheme
{
IWindow *CreateWindow()
{
return new XPWindow();
}
IButton *CreateButton()
{
return new XPButton();
}
};
/*
* VistaTheme
*/
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 |