[C++] Abstract Factory Pattern 实作
一、简介
1. 抽象工厂属于设计模式的"创建模式"分类。
2. 抽象工厂提供了一个接口,可以创建一个object,而不需要显式地、明确地指定object的类型。
3. 抽象工厂成员:
Abstract Factory: 工厂的抽象类。
Concrete Factory: 工厂的实作类,继承AbstractFactory。
AbstractProduct: 产品的抽象类,定义一个产品的种类,例如食物、CPU、衣服。
ConcreteProduct: 产品抽象类的实作类,继承AbstractProduct,例如面包、Intel CPU、T-Shirt。
Client: 用户类,提供一个接口来存取AbstractFactory和AbstractProduct两抽象类。
二、差异
1. 在简单工厂(Simply Factory)中,使用一个工厂生成所有同种类产品实例。
2. 在工厂方法(Factory Method)中,每个工厂各自生成一个产品实例,
同时,每个不同的工厂所生成的产品实例都是属于同种类的。
3. 在抽象工厂(Abstract Factory)中,每个工厂可以生成一个或多个"不同种类"的产品实例,
因此抽象工厂允许存在多个工厂、多种产品。
三、使用场景
1. 希望将属于不同种类却在某意义上相关联的产品实例之生成做集中管理。2. 希望藉由一个接口,生成不同种类的产品实例。
3. 希望扩展现有种类下的新产品或是扩增产品族,而不影响当前模型的结构层次。
四、释疑Q&A
Q: 当有一个新的产品类出现时,工厂想要生成这个新类的产品实例,此时需要修改原有模组,在抽象的Creator类和具体的ConcreteCreator类新增生成方法,如此便违反了OCP,
抽象工厂模式的设计是否有问题?
A: 抽象工厂主要是让用户可以对现有的多种不同产品进行生成,
针对不同情况下的需求分别以各个工厂为一模块单位管理旗下多种产品实例生成,
再以抽象工厂接口让用户认识所有工厂,达到抽象化的效果。
五、实作
此处给出了一个抽象工厂实例的UML类别图以及代码
AbstractFactoryDemo.cpp
#include "windows.h"
#include <string>
#include <iostream>
class Cpu
{
public:
Cpu(void){}
~Cpu(void){}
virtual std::string Show()=0;
};
class IntelCpu : public Cpu
{
public:
IntelCpu(void){}
~IntelCpu(void){}
std::string Show(){ return "Intel CPU"; }
};
class AmdCpu : public Cpu
{
public:
AmdCpu(void){}
~AmdCpu(void){}
std::string Show(){ return "AMD CPU"; }
};
class DisplayCard
{
public:
DisplayCard(void){}
~DisplayCard(void){}
virtual std::string Show()=0;
};
class NvidiaDisplayCard : public DisplayCard
{
public:
NvidiaDisplayCard(void){}
~NvidiaDisplayCard(void){}
std::string Show(){ return "Nvidia DisplayCard";}
};
class AmdDisplayCard : public DisplayCard
{
public:
AmdDisplayCard(void){}
~AmdDisplayCard(void){}
std::string Show(){ return "AMD DisplayCard";}
};
class AbstractFactory
{
public:
AbstractFactory(void){}
~AbstractFactory(void){}
virtual Cpu* CreateCpu()=0;
virtual DisplayCard* CreateDisplayCard()=0;
};
class FactoryA : public AbstractFactory
{
public:
FactoryA(void){}
~FactoryA(void){}
Cpu* CreateCpu(){ return new IntelCpu(); }
DisplayCard* CreateDisplayCard(){ return new NvidiaDisplayCard(); }
};
class FactoryB : public AbstractFactory
{
public:
FactoryB(void){}
~FactoryB(void){}
Cpu* CreateCpu(){ return new AmdCpu(); }
DisplayCard* CreateDisplayCard(){ return new AmdDisplayCard(); }
};
class Pc
{
public:
static std::string FACTORY_A;
static std::string FACTORY_B;
Pc(std::string name, std::string strFactory) : name(name)
{
if(strFactory==Pc::FACTORY_A)
this->abstractFactory=new FactoryA();
else if(strFactory==Pc::FACTORY_B)
this->abstractFactory=new FactoryB();
else
{
printf("Factory error!");
return;
}
this->strFactory=strFactory;
this->cpu=abstractFactory->CreateCpu();
this->dc=abstractFactory->CreateDisplayCard();
}
~Pc(void){}
void ShowDetail(){ std::cout<<this->name<<" is created by "<<this->strFactory<<": "<<"contain "<<this->cpu->Show()<<", "<<this->dc->Show()<<".\n"; }
private:
AbstractFactory* abstractFactory;
Cpu* cpu;
DisplayCard* dc;
std::string strFactory;
std::string name;
};
std::string Pc::FACTORY_A="Factory-A";
std::string Pc::FACTORY_B="Factory-B";
void main()
{
Pc *pc1=new Pc("PC1", Pc::FACTORY_A);
pc1->ShowDetail();
Pc *pc2=new Pc("PC2", Pc::FACTORY_B);
pc2->ShowDetail();
system("pause");
return;
}
六、延伸
Singleton Pattern、Manager Pattern