C++ 设计模式之抽象工厂模式
简介
1、抽象工厂模式(Abstract Factory Pattern)是一种创建型设计模式,它提供了一种方式来封装一组具有共同主题的单个工厂,而不需要指定它们的具体类。抽象工厂模式允许客户端使用抽象的接口来创建一系列相关或依赖的对象,而不需要指定它们具体的类。
2、抽象工厂模式 (Abstract Factory)应用场景包括但不限于:
2.1、系统独立于如何创建、组成和表示它的产品 :系统应该对产品类的实现细节和创建过程无需了解。
2.2、系统需要多个产品系列中的一个来配置 :可以动态地更改产品系列。
2.3、系统需要提供产品库的类,且只想显示它们的接口而不是实现 。
3、抽象工厂模式的构成
3.1、抽象工厂(Abstract Factory):声明一个用于创建对象的接口。
class GUIFactory
{
public:
virtual Button* CreateButton() = 0;
virtual ~GUIFactory() {};
};
3.2、具体工厂(Concrete Factory):实现抽象工厂接口,创建具体产品的实例。
class WindowsFactory : public GUIFactory
{
public:
Button* CreateButton();
Checkbox* CreateCheckbox();
};
3.3、抽象产品(Abstract Product):声明产品的接口。
class Button
{
public:
virtual void paint() = 0;
virtual ~Button() {};
};
3.4、具体产品(Concrete Product):实现抽象产品接口,是具体工厂创建的对象。
class WindowsButton : public Button
{
public:
void paint();
};
4、抽象工厂模式优点:
4.1、分离具体的实现 :客户端代码通过接口操作实例,不依赖于具体的类实现。
4.2、易于交换产品系列 :因为具体工厂类在一个应用中只需要在初始化的时候出现一次,这使得改变一个应用的具体工厂变得十分容易。只需要改变具体工厂即可使用不同的产品配置。
4.3、增加新的产品系列容易 :扩展新的产品族比较方便,符合开闭原则。
5、抽象工厂模式缺点:
5.1、难以支持新种类的产品 :一旦工厂类中定义好了创建产品的方法后,如果需要添加新产品就不容易,因为抽象工厂接口确定后不容易修改。
5.2、复杂度增加 :随着产品族的增加,相关的具体工厂和产品类的数量也会增加,这会使系统更加复杂。
简单示例
1、定义
// 抽象产品
class Button
{
public:
virtual void paint() = 0;
virtual ~Button() {};
};
class Checkbox
{
public:
virtual void paint() = 0;
virtual ~Checkbox() {};
};
// 具体产品
class WindowsButton : public Button
{
public:
void paint();
};
class MacButton : public Button
{
public:
void paint();
};
class WindowsCheckbox : public Checkbox
{
public:
void paint();
};
class MacCheckbox : public Checkbox
{
public:
void paint();
};
// 抽象工厂
class GUIFactory
{
public:
virtual Button* CreateButton() = 0;
virtual Checkbox* CreateCheckbox() = 0;
virtual ~GUIFactory() {};
};
// 具体工厂
class WindowsFactory : public GUIFactory
{
public:
Button* CreateButton();
Checkbox* CreateCheckbox();
};
class MacFactory : public GUIFactory
{
public:
Button* CreateButton();
Checkbox* CreateCheckbox();
};
class Application
{
public:
Application(GUIFactory* f);
~Application();
void CreateUI();
void Paint();
private:
GUIFactory* factory;
Button* button;
Checkbox* checkbox;
};
2、实现
void WindowsButton::paint()
{
std::cout << "WindowsButton" << std::endl;
}
void MacButton::paint()
{
std::cout << "MacButton" << std::endl;
}
void WindowsCheckbox::paint()
{
std::cout << "WindowsCheckbox" << std::endl;
}
void MacCheckbox::paint()
{
std::cout << "MacCheckbox" << std::endl;
}
Button* WindowsFactory::CreateButton()
{
return new WindowsButton();
}
Checkbox* WindowsFactory::CreateCheckbox()
{
return new WindowsCheckbox();
}
Button* MacFactory::CreateButton()
{
return new MacButton();
}
Checkbox* MacFactory::CreateCheckbox()
{
return new MacCheckbox();
}
Application::Application(GUIFactory* f) : factory(f), button(nullptr), checkbox(nullptr)
{
}
Application::~Application()
{
if (factory)
{
delete factory;
}
if (button)
{
delete button;
}
if (checkbox)
{
delete checkbox;
}
}
void Application::CreateUI()
{
button = factory->CreateButton();
checkbox = factory->CreateCheckbox();
}
void Application::Paint()
{
button->paint();
checkbox->paint();
}
3、调用
GUIFactory* factory;
#ifdef WIN32
factory = new WindowsFactory();
#else
factory = new MacFactory();
#endif // WIN32
Application app(factory);
app.CreateUI();
app.Paint();