工厂模式简介
工厂模式属于创建型设计模式,它将对象实例化的具体过程封装起来,取代直接new对象的方式,使对象实例化与业务代码逻辑隔离。被创建的产品对象所属的类一般都具有相同的父类。工厂模式分为:简单工厂模式,工厂模式和抽象工厂模式。
简单工厂模式
我们将要创建的对象叫做“产品”,把创建“产品”的对象叫做“工厂”。简单工厂模式就是由一个工厂类来决定创建哪一种“产品”类的对象。简单工厂模式违背了“开闭原则”,所以可以看做是不同工厂模式的一个特例,当要创建的对象较少时,可以使用简单工厂模式来实现创建对象。
举个例子,然后代码简单实现。例如,手机的组成包括电池、屏幕和主板等,不同手机厂商造的手机所使用的具体配件也不同,下面实现了苹果、华为和小米三种手机,由不同的工厂来进行创建。
不用设计模式实现:定义一个手机产品的基类,有电池、屏幕和主板三种属性。不同的手机实现一个子类分别继承手机产品的基类。然后在主函数中使用new方式,将手机基类指针指向不同的手机子类。
#include<iostream>
#include<string>
using namespace std;
class phone
{
public:
phone(string battery,string screen,string motherboard):
m_battery(battery),
m_screen(screen),
m_motherboard(motherboard){}
virtual ~phone(){}
private:
string m_battery;
string m_screen;
string m_motherboard;
};
class iphone:public phone{
public:
iphone(string battery,string screen,string motherboard):
phone(battery,screen,motherboard){
cout << "iphone product!"<< endl;
}
virtual ~iphone(){}
};
class huawei:public phone{
public:
huawei(string battery,string screen,string motherboard):
phone(battery,screen,motherboard){
cout << "huawei product!"<< endl;
}
virtual ~huawei(){}
};
class xiaomi:public phone{
public:
xiaomi(string battery,string screen,string motherboard):
phone(battery,screen,motherboard){
cout << "xiaomi product!"<< endl;
}
virtual ~xiaomi(){}
};
int main()
{
phone* phoneProduct1 = new iphone("Li","LED","A16");
phone* phoneProduct2 = new huawei("Li","OLED","QiLin");
phone* phoneProduct3 = new xiaomi("Li","OLED","MiU");
return 0;
}
上面这种方式使用new+具体的类名来创建对象是一种依赖具体类名的紧耦合关系,只要新增了新的手机类,就需要知道类名,非常低效和难以维护。 下面使用简单工厂模式来实现创建手机。只需要在简单工厂模式的工厂类的创建方法中输入手机的品牌,就可以得到具体手机子类的对象。
class SimplePhoneFactory{
public:
phone* CreatePhone(string brand){
if(brand == "iphone"){
return new iphone("Li","LED","A16");
}
else if(brand == "huawei")
{
return new huawei("Li","OLED","QiLin");
}
else if(brand == "xiaomi"){
return new xiaomi("Li","OLED","MiU");
}
else{
return nullptr;
}
}
};
int main()
{
//简单工厂模式
SimplePhoneFactory simplefactory;
phone* phoneProduct = simplefactory.CreatePhone("huawei");
}
简单工厂模式的缺点也很明显,就是当需要新增一个手机产品类时,需要在工厂类创建方法中新增对新的手机产品类的支持,这违反了六大设计原则之中的“开闭原则”。而工厂模式可以解决这个问题。
工厂模式
工厂模式又被称为工厂方法模式和多态工厂模式。工厂模式通过创建新的工厂类来创建新的产品类型,而不会修改原来的创建方法函数。
例如当新增苹果、华为和小米手机产品时,通过新增苹果、华为和小米的手机工厂类,来实现对不同手机的创建,然后通过创建产品函数,将所有工厂的共同基类传入,将得到工厂基类所指向的具体子类工厂创建的手机产品。
//抽象手机工厂基类
class phoneFactory{
public:
phoneFactory(){}
virtual ~phoneFactory(){}
virtual phone* createPhone() = 0;
};
//苹果手机工厂类
class iphoneFactory:public phoneFactory{
public:
virtual phone* createPhone(){
return new iphone("Li","LED","A16");
}
};
//华为手机工厂类
class huaweiFactory:public phoneFactory{
public:
virtual phone* createPhone(){
return new huawei("Li","OLED","QiLin");
}
};
//小米手机工厂类
class xiaomiFactory:public phoneFactory{
public:
virtual phone* createPhone(){
return new xiaomi("Li","OLED","MiU");
}
};
//创建手机产品方法接口
phone* createFactory_use(phoneFactory* factory){
return factory->createPhone();
}
int main()
{
//工厂模式
//苹果手机创建
phoneFactory* factory1 = new iphoneFactory();
phone* iphone = createFactory_use(factory1);
//华为手机创建
phoneFactory* factory2 = new huaweiFactory();
phone* huawei = createFactory_use(factory2);
//小米手机创建
phoneFactory* factory3 = new xiaomiFactory();
phone* xiaomi = createFactory_use(factory3);
return 0;
}
如果后续需要继续增加新类,可以通过增加扩展新的工厂类和产品类来实现而不是修改现有代码的方式,符合“开闭原则”。但是上述实现也有一个缺点,就是每实现一个手机类,就需要实现一个对应的手机工厂类,比较麻烦,可以通过模板来优化。
template<typename T>
class specificPhone:public phoneFactory{
public:
virtual phone* createPhone(){
return new T("Li","OLED","");
}
};
//创建手机产品方法接口
phone* createFactory_use(phoneFactory* factory){
return factory->createPhone();
}
int main()
{
//工厂模式
phoneFactory* phonefactory = new specificPhone<huawei>();
phone* huawei = createFactory_use(phonefactory);
return 0;
}
抽象工厂模式
具体应用场景1-制造国家版本分类
还是生产以上三款手机,但是手机分在哪个国家生产,比如在中国大陆生产(国行)、在中国香港生产(港版)和在美国生产叫(美版),这时候需要你在不同的国家创建不同的手机版本,相同手机在不同的国家生产的保修期限不同。
目前的手机有三款:华为、苹果、小米。通过排列组合可以得到9种不同的手机子类。那么有没有一种方法能够让一个工厂子类能够创建多种具有相同规则的手机对象呢,这就是抽象工厂模式的思想。
需要引入两个概念:产品族和产品等级结构
抽象工厂模式按照产品族来生产产品(产地一样的用一个工厂来生产),即一个国家只有一个工厂,该工厂负责生产本地区的所有产品。
可以通过创建一个抽象工厂类,这个抽象类里有三个生产接口,分别来生产不同的手机,不同的国家都可以继承这个抽象工厂类,来重写这三个生产接口。这样就可以生产出9中不同版本的手机了。
//抽象手机工厂类
class AbstractPhoneFatory{
public:
AbstractPhoneFatory(){};
virtual phone* create_huawei() = 0;
virtual phone* create_iphone() = 0;
virtual phone* create_xiaomi() = 0;
};
//国行版本的手机工厂
class ChinesePhoneFactory:public AbstractPhoneFatory{
public:
virtual phone* create_huawei(){
cout<<"chinese huawei create!"<<endl;
return new huawei("chinese huawei battery","chinese huawei screen","chinese huawei motherboard");
}
virtual phone* create_iphone(){
cout<<"chinese iphone create!"<<endl;
return new iphone("chinese iphone battery","chinese iphone screen","chinese iphone motherboard");
}
virtual phone* create_xiaomi(){
cout<<"chinese xiaomi create!"<<endl;
return new xiaomi("chinese xiaomi battery","chinese xiaomi screen","chinese xiaomi motherboard");
}
};
//港版的手机工厂
class HongKongPhoneFactory:public AbstractPhoneFatory{
public:
virtual phone* create_huawei(){
cout<<"HongKong huawei create!"<<endl;
return new huawei("HongKong huawei battery","HongKong huawei screen","HongKong huawei motherboard");
}
virtual phone* create_iphone(){
cout<<"HongKong iphone create!"<<endl;
return new iphone("HongKong iphone battery","HongKong iphone screen","HongKong iphone motherboard");
}
virtual phone* create_xiaomi(){
cout<<"HongKong xiaomi create!"<<endl;
return new xiaomi("HongKong xiaomi battery","HongKong xiaomi screen","HongKong xiaomi motherboard");
}
};
//美版的手机工厂
class USPhoneFactory:public AbstractPhoneFatory{
public:
virtual phone* create_huawei(){
cout<<"US huawei create!"<<endl;
return new huawei("US huawei battery","US huawei screen","US huawei motherboard");
}
virtual phone* create_iphone(){
cout<<"US iphone create!"<<endl;
return new iphone("US iphone battery","US iphone screen","US iphone motherboard");
}
virtual phone* create_xiaomi(){
cout<<"US huawei create!"<<endl;
return new xiaomi("US xiaomi battery","US xiaomi screen","US xiaomi motherboard");
}
};
int main()
{
//抽象工厂模式
AbstractPhoneFatory* abPhoneFactory1 = new ChinesePhoneFactory();
//生产国行版华为
phone* phone1 = abPhoneFactory1->create_huawei();
AbstractPhoneFatory* abPhoneFactory2 = new HongKongPhoneFactory();
//生产港版iphone
phone* phone2 = abPhoneFactory2->create_iphone();
AbstractPhoneFatory* abPhoneFactory3 = new USPhoneFactory();
//生产美版xiaomi
phone* phone3 = abPhoneFactory3->create_xiaomi();
return 0;
}
具体应用场景2-不同厂商生产不同产品
例如一个手机的配件是由不同的厂商生产的,电池、屏幕、主板;这些部件是由三个国家的厂商制作,中国、日本、美国;现在需要对两种手机有制作要求,华为手机需要中国的电池、中国的屏幕和中国的主板;苹果需要中国的电池、日本的屏幕和美国的主板。
实现一个抽象工厂类,三个抽象函数来生产三个不同的零件,不同的厂商通过继承和多态来实现生产属于自己的三种部件。最后设置手机类,通过传入三种零件的抽象指针来完成组装手机。
//电池抽象类
class battery{
public:
virtual void getName() = 0;
};
//屏幕抽象类
class screen{
public:
virtual void getName() = 0;
};
//主板抽象类
class motherBoard{
public:
virtual void getName() = 0;
};
//手机产品类
class phoneProduct{
public:
phoneProduct(battery* bt,screen* sc,motherBoard* mb):
m_bt(bt),m_sc(sc),m_mb(mb){}
void assemble(){
cout<<"create phone!"<<endl;
m_bt->getName();
m_sc->getName();
m_mb->getName();
}
private:
battery* m_bt;
screen* m_sc;
motherBoard* m_mb;
};
//抽象工厂类
class AbstractPhoneFactory{
public:
virtual battery* create_battery() = 0;
virtual screen* create_screen() = 0;
virtual motherBoard* create_motherBorad() = 0;
};
//华为厂商实现三个零件
class HuaweiBattery:public battery{
public:
virtual void getName(){
cout<<"chinese huawei battery!"<<endl;
}
};
class HuaweiScreen:public screen{
public:
virtual void getName(){
cout<<"chinese huawei screen!"<<endl;
}
};
class HuaweiMotherBoard:public motherBoard{
public:
virtual void getName(){
cout<<"chinese huawei motherboard!"<<endl;
}
};
//华为工厂
class Huaweifactory:public AbstractPhoneFactory{
public:
virtual battery* create_battery(){
return new HuaweiBattery();
}
virtual screen* create_screen(){
return new HuaweiScreen();
}
virtual motherBoard* create_motherBorad(){
return new HuaweiMotherBoard();
}
};
//iphone厂商实现三个零件
class iphoneBattery:public battery{
public:
virtual void getName(){
cout<<"chinese iphone battery!"<<endl;
}
};
class iphoneScreen:public screen{
public:
virtual void getName(){
cout<<"japan iphone screen!"<<endl;
}
};
class iphoneMotherBoard:public motherBoard{
public:
virtual void getName(){
cout<<"US iphone motherboard!"<<endl;
}
};
//iphone工厂
class iphonefactory:public AbstractPhoneFactory{
public:
virtual battery* create_battery(){
return new iphoneBattery();
}
virtual screen* create_screen(){
return new iphoneScreen();
}
virtual motherBoard* create_motherBorad(){
return new iphoneMotherBoard();
}
};
int main()
{
//创建华为手机
//1.创建华为工厂
AbstractPhoneFactory* huaweiFactory = new Huaweifactory();
//2.创建华为的零件
battery* huaweiBt = huaweiFactory->create_battery();
screen* huaweiSc = huaweiFactory->create_screen();
motherBoard* huaweim = huaweiFactory->create_motherBorad();
//3.组装华为手机
phoneProduct* huaweiPhone = new phoneProduct(huaweiBt,huaweiSc,huaweim);
huaweiPhone->assemble();
//创建iphone手机
//1.创建iphone工厂
AbstractPhoneFactory* iphoneFactory = new iphonefactory();
//2.创建华为的零件
battery* iphoneBt = iphoneFactory->create_battery();
screen* iphoneSc = iphoneFactory->create_screen();
motherBoard* iphonem = iphoneFactory->create_motherBorad();
//3.组装华为手机
phoneProduct* iPhone = new phoneProduct(iphoneBt,iphoneSc,iphonem);
iPhone->assemble();
return 0;
}
总结
实现复杂度:简单工厂模式最简单,工厂方法模式次之,抽象工厂模式最复杂。
如果将简单工厂模式的代码修改得符合“开闭原则”,就变成了工厂模式;如果修改工厂模式的代码,使得一个工厂支持多个产品的生产,那就成了抽象工厂模式。