抽象工厂模式:提供一个创建一系列相关或相互依赖对象的接口,而无需指定它们具体的类。
适用场景:
- 客户端(应用层)不依赖于产品类实例如何被创建、实现等细节
- 强调一系列相关的产品对象(属于同一产品族)一起使用创建对象需要大量的重复代码
- 提供一个产品类的库,所有的产品以同样的接口出现,从而使得客户端不依赖于具体的实现
抽象工厂模式的结构图
对应上面的的抽象工厂模式的结构图
我们对下面的对象进行抽象
假设这里有两种车,奔驰 宝马
有两个国家的品牌,中国,美国
中国生产的叫 中国奔驰,中国宝马
美国生产的叫 美国奔驰,美国宝马
抽象工厂模式的好处:
- 易于交换产品系列,由于具体的产品类,在一个应用中只需要在初始化的时候出现一次,这就使得改变一个应用的具体工厂变得非常容易,它只需要改变具体工厂即可使用不同的产品配置。
- 它让具体的创建实例过程与客户端分离,客户端通过它们的抽象接口操纵实例,产品的具体类名也被具体工厂的实现分离,不会出现在客户端的代码中。
缺点:
- 规定了所有可能被创建的产品集合,产品簇中扩展新的产品困难;
- 增加了系统的抽象性和理解难度
下面是代码的实现
#include <iostream>
#include <string>
using namespace std;
//对工厂进行抽象
class BMW
{
public:
BMW(string str):name(str){}
virtual void run() = 0;
protected:
string name;
};
class BENZ
{
public:
BENZ(string str):name(str){}
virtual void run() = 0;
protected:
string name;
};
class ChinaBMW:public BMW
{
public:
ChinaBMW(string str):BMW(str){}
void run() { cout << name << "宝马车在路上" << endl;}
};
class ChinaBENZ:public BENZ
{
public:
ChinaBENZ(string str):BENZ(str){}
void run() {cout << name << " 奔驰车在路上 " << endl;}
};
class AmericaBMW:public BMW
{
public:
AmericaBMW(string str):BMW(str){}
void run() { cout << name << "宝马车在路上" << endl; }
};
class AmericaBENZ:public BENZ
{
public:
AmericaBENZ(string str):BENZ(str){}
void run() {cout << name << " 奔驰车在路上 " << endl;}
};
//抽象工厂类
class CarFactory
{
public:
virtual BMW *createBMWCar() = 0;
virtual BENZ *createBENZCar() = 0;
};
class AmericaFactort:public CarFactory
{
public:
BMW *createBMWCar() { return new AmericaBMW("美国"); }
BENZ *createBENZCar() { return new AmericaBENZ("美国"); }
};
class ChinaFactory:public CarFactory
{
public:
BMW *createBMWCar() { return new AmericaBMW("中国"); }
BENZ *createBENZCar() { return new AmericaBENZ("中国"); }
};
int main()
{
CarFactory *china = new ChinaFactory();
CarFactory *america = new AmericaFactort();
BMW *CBMW = china->createBMWCar();
BENZ *CBNEA = china->createBENZCar();
BMW *ABMW = america->createBMWCar();
BENZ *ABENZ = america->createBENZCar();
CBMW->run();
CBNEA->run();
ABMW->run();
ABENZ->run();
return 0;
}
在上面的模式中,如果想要添加一种产品,就要修改CarFactory,AmericaFactort,ChinaFactory,代码需要大批量的修改,下面用简单工厂模式改进抽象工厂模式,去掉
CarFactory,AmericaFactort,ChinaFactory这三个工厂类,用一个Car 来代替
class Car
{
public:
void setCountry(char ch)
{
c = ch;
}
BMW *createBMWCar()
{
switch (c)
{
case 'c':
return new ChinaBMW("中国");
case 'a':
return new AmericaBMW("美国");
default:
break;
}
}
BENZ *createBENZCar()
{
switch (c)
{
case 'c':
return new ChinaBENZ("中国");
case 'a':
return new AmericaBENZ("美国");
default:
break;
}
}
private:
char c; //设置哪个国家标志
};
int main()
{
Car car;
car.setCountry('c');
BENZ* cbenz = car.createBENZCar();
BMW * cbmw = car.createBMWCar();
cbenz->run();
cbmw->run();
car.setCountry('a');
BENZ *abenz = car.createBENZCar();
BMW *abmw = car.createBMWCar();
abenz->run();
abmw->run();
return 0;
}
在改进后的模式中,如果要添加一种车,只要在Car 类中添加一个函数即可,但是如果要添加一个厂商,比如英国,则需要在所有的函数中添加case分支。