适用的场景:
1产品品种类繁多,需要分系列,还会出现子系列的情况适合使用抽象工厂模式
2需要经常加入新型号的产品
以下面场景为例:
假设目前存在汽车,公交车,四轴车,货车四类产品。
现在由不同的供应商(BYD X SANY)提供,并且每类产品有不同的信号。而假设byd只制造汽车,公交车,小鹏只造汽车和四轴汽车,三一重工只制造轮船和货车。这样不同的供应商在制作的产品上存在交集
此场景下,比较推荐抽象工厂模式,首先设置了虚基类Product,以及商品类Car,Bus,Ship ,Hevicotor .以及工厂byd工厂,X工厂,和SANY工厂分别处理各自的业务。
#include <iostream>
#include <vector>
#include <utility>
#include <random>
using namespace std;
class Product
{
public:
std::string producter;
std::string type;
virtual void info() = 0;
void mainInfo()
{
std::cout << producter << " " << type << std::endl;
}
void setMainInfo(std::string p , std::string t)
{
producter = p;
type = t;
}
};
class Car:public Product
{
public:
std::string color;
double max_speed;
int capacity = 4;
Car(string s,double maxs):color(s),max_speed(maxs){}
Car(string s,double maxs , int cap):color(s),max_speed(maxs),capacity(cap){}
void info() override
{
std::cout << "color:" << color << " maxs:" << max_speed << " capacity:" << capacity << std::endl;
}
};
class Bus:public Product
{
public:
std::string color;
const int capacity = 50;
int cnt_door;
Bus(string s,int cd):color(s),cnt_door(cd){}
void info() override
{
std::cout << "color:" << color << " doors:" << cnt_door << " capacity:" << capacity << std::endl;
}
};
class Ship:public Product
{
public:
std::string color;
const int capacity = 1000;
int cnt_door;
int mass;
Ship(string s,int cd , int m):color(s),cnt_door(cd),mass(m){}
void info() override
{
std::cout << "color:" << color << " doors:" << cnt_door << " mass:" << mass << std::endl;
}
};
class Hevicoter:public Product
{
public:
std::string color;
const int capacity = 4;
Hevicoter(std::string c):color(c){}
void info() override
{
std::cout << "color:" << color << std::endl;
}
};
class Truck:public Product
{
public:
std::string color;
Truck(std::string color):color(color){}
void info() override
{
std::cout << "color:" << color << std::endl;
}
};
class Factory
{
public:
virtual Product*createProduct() = 0;
};
//----------------------byd.h-------------------------------------------------
class BydCar:public Car
{
public:
BydCar(std::string car_type, std::string color , double maxs):Car(color,maxs)
{
setMainInfo("byd", car_type);
}
};
class BydBus:public Bus
{
public:
BydBus(std::string car_type, std::string color ,int cd):Bus(color,cd)
{
setMainInfo("byd", car_type);
}
};
class BydFactory:Factory
{
public:
std::string indent;
std::string color;
std::string type_;
double max_speed;
int capacity = 4;
int cnt_door;
Product*createProduct() override
{
if(indent == "car")
{
BydCar*byd_car = new BydCar(type_,color,max_speed);
return byd_car;
}
else if(indent == "bus")
{
BydBus*byd_bus = new BydBus(type_,color,cnt_door);
return byd_bus;
}
return nullptr;
}
};
//--------------------------------xiaopeng.h-----------------------------------
class XCar:public Car
{
public:
XCar(std::string car_type, std::string color , double maxs):Car(color,maxs)
{
setMainInfo("X", car_type);
}
};
class XHevicoter:public Hevicoter
{
public:
XHevicoter(std::string car_type, std::string color ):Hevicoter(color)
{
setMainInfo("X", car_type);
}
};
class XFactory:Factory
{
public:
std::string indent;
std::string color;
std::string type_;
double max_speed;
int capacity = 4;
Product*createProduct() override
{
if(indent == "car")
{
XCar*x_car = new XCar(type_,color,max_speed);
return x_car;
}
else if(indent == "hevicoter")
{
XHevicoter*x_hevicoter = new XHevicoter(type_,color);
return x_hevicoter;
}
return nullptr;
}
};
//------------------------------SANY.h------------------------------------------
class SanyShip:public Ship
{
public:
SanyShip(std::string car_type, std::string color , int cnt_doors , int mass):Ship(color,cnt_doors , mass)
{
setMainInfo("SANY", car_type);
}
};
class SanyTruck:public Truck
{
public:
SanyTruck(std::string car_type,std::string color):Truck(color)
{
setMainInfo("SANY" , car_type);
}
};
class SanyFactory:Factory
{
public:
std::string indent;
std::string color;
std::string type_;
int cnt_doors;
int mass;
int capacity = 4;
Product*createProduct() override
{
if(indent == "ship")
{
SanyShip*sany_ship = new SanyShip(type_,color,cnt_doors,mass);
return sany_ship;
}
else if(indent == "truck")
{
SanyTruck*sany_ship = new SanyTruck(type_,color);
return sany_ship;
}
return nullptr;
}
};
int main()
{
Product *p1, *p2;
BydFactory byd_factory;
byd_factory.color = "red";
byd_factory.indent = "car";
byd_factory.type_ = "Dolploin";
byd_factory.max_speed = 200.0;
p1 = byd_factory.createProduct();
p1->mainInfo();
p1->info();
XFactory x_factory;
x_factory.color = "white";
x_factory.indent = "car";
x_factory.type_ = "P7";
x_factory.max_speed = 200.0;
p2 = x_factory.createProduct();
p2->mainInfo();
p2->info();
}
后续假设需要加上华为的汽车或手机,小米的汽车或手机,需要先设计手机类Phone,随后创建HuaweiPhone和MiPhone。最后创建各自的工厂。
抽象工厂的优点:
1在产品种类较多,而且需要分系列甚至存在诸多子系列的时方便进行管理。
2在以上场景下,抽象工厂模式更加方便进行维护。即添加新的系列产品较其他模式更加方便。