这种类型的设计模式属于创建型模式,它提供了一种创建对象的最佳方式。在工厂模式中,我们在创建对象时不会对客户端暴露创建逻辑,并且是通过使用一个共同的接口来指向新创建的对象。
工厂模式主要使用了C++的多态特性。将存在继承关系的类,通过一个工厂类创建对应的子类(派生类)对象。在项目复杂的情况下,可以便于子类对象的创建。
工厂模式的实现方式可分别简单工厂模式、工厂方法模式、抽象工厂模式,每个实现方式都存在优和劣。
以制鞋厂为例对这三种工厂模式进行举例说明
1. 简单工厂模式
1.1 UML图
类比情形:鞋厂可以指定生产耐克、阿迪达斯和李宁牌子的鞋子。哪个鞋炒的火爆,老板就生产哪个,看形势生产。
UML图如下:
一个工厂类包含如下三要素:
- 工厂类:工厂模式的核心类,会定义一个用于创建指定的具体实例对象的接口。
- 抽象产品类:是具体产品类的继承的父类或实现的接口。
- 具体产品类:工厂类所创建的对象就是此具体产品实例。
1.2 具体代码实现
/**
* Shoes为鞋子的抽象类(基类),接口函数为Show(),用于显示鞋子广告。
* NiKeShoes、AdidasShoes、LiNingShoes为具体鞋子的类,分别是耐克、阿迪达斯和李 宁鞋牌的鞋,它们都继承于Shoes抽象类。
*/
#include<iostream>
using namespace std;
// 鞋子抽象类
class Shoes
{
public:
virtual ~Shoes() {}
virtual void Show() = 0; // 纯虚函数在子类实现
};
// 耐克鞋子
class NiKeShoes : public Shoes
{
public:
void Show()
{
std::cout << "我是耐克球鞋,我的广告语:Just do it" << std::endl;
}
};
// 阿迪达斯鞋子
class AdidasShoes : public Shoes
{
public:
void Show()
{
std::cout << "我是阿迪达斯球鞋,我的广告语:Impossible is nothing" << std::endl;
}
};
// 李宁鞋子
class LiNingShoes : public Shoes
{
public:
void Show()
{
std::cout << "我是李宁球鞋,我的广告语:Everything is possible" << std::endl;
}
};
enum SHOES_TYPE
{
NIKE,
LINING,
ADIDAS
};
// 总鞋厂
class ShoesFactory
{
public:
// 根据鞋子类型创建对应的鞋子对象
Shoes *CreateShoes(SHOES_TYPE type)
{
switch (type)
{
case NIKE:
return new NiKeShoes();
break;
case LINING:
return new LiNingShoes();
break;
case ADIDAS:
return new AdidasShoes();
break;
default:
return NULL;
break;
}
}
};
int main()
{
ShoesFactory shoesfactory;
Shoes* ptr_nike_shoes = shoesfactory.CreateShoes(NIKE);
if(ptr_nike_shoes != NULL)
{
ptr_nike_shoes->Show();
delete ptr_nike_shoes;
ptr_nike_shoes = NULL;
}
Shoes* ptr_adidas_shoes = shoesfactory.CreateShoes(ADIDAS);
if(ptr_adidas_shoes != NULL)
{
ptr_adidas_shoes->Show();
delete ptr_adidas_shoes;
ptr_adidas_shoes = NULL;
}
Shoes* ptr_lining_shoes = shoesfactory.CreateShoes(LINING);
if(ptr_lining_shoes != NULL)
{
ptr_lining_shoes->Show();
delete ptr_lining_shoes;
ptr_lining_shoes = NULL;
}
return 0;
}
2. 工厂方法模式
2.1 UML图
**类比情形:**现各类鞋子抄的非常火热,于是为了大量生产每种类型的鞋子,则要针对不同品牌的鞋子开设独立的生产线,那么每个生产线就只能生产同类型品牌的鞋。
UML图:
工厂方法模式的结构组成:
- 抽象工厂类:工厂方法模式的核心类,提供创建具体产品的接口,由具体工厂类实现。
- 具体工厂类:继承于抽象工厂,实现创建对应具体产品对象的方式。
- 抽象产品类:它是具体产品继承的父类(基类)。
- 具体产品类:具体工厂所创建的对象,就是此类。
2.2 具体代码实现
#include<iostream>
using namespace std;
// 鞋子抽象类
class Shoes
{
public:
virtual ~Shoes() {}
virtual void Show() = 0; // 纯虚函数在子类实现
};
// 耐克鞋子
class NiKeShoes : public Shoes
{
public:
void Show()
{
std::cout << "我是耐克球鞋,我的广告语:Just do it" << std::endl;
}
};
// 阿迪达斯鞋子
class AdidasShoes : public Shoes
{
public:
void Show()
{
std::cout << "我是阿迪达斯球鞋,我的广告语:Impossible is nothing" << std::endl;
}
};
// 李宁鞋子
class LiNingShoes : public Shoes
{
public:
void Show()
{
std::cout << "我是李宁球鞋,我的广告语:Everything is possible" << std::endl;
}
};
// 总鞋厂实现
class ShoesFactory
{
public:
virtual Shoes *CreateShoes() = 0;
virtual ~ShoesFactory() {}
};
// 耐克生产鞋厂
class NikeProducer : public ShoesFactory
{
public:
Shoes *CreateShoes()
{
return new NiKeShoes();
}
};
// 阿迪达斯生产鞋厂
class AdidasProductor : public ShoesFactory
{
public:
Shoes *CreateShoes()
{
return new AdidasShoes();
}
};
// 李宁生产鞋厂
class LiningProductor : public ShoesFactory
{
public:
Shoes *CreateShoes()
{
return new LiNingShoes;
}
};
int main()
{
// ================ 生产耐克流程 ==================== //
// 鞋厂开设耐克生产线
ShoesFactory *niKeProducer = new NikeProducer();
// 耐克生产线产出球鞋
Shoes *nikeShoes = niKeProducer->CreateShoes();
// 耐克球鞋广告喊起
nikeShoes->Show();
// 释放资源
delete nikeShoes;
delete niKeProducer;
// ================ 生产阿迪达斯流程 ==================== //
// 鞋厂开设阿迪达斯生产者
ShoesFactory *adidasProducer = new AdidasProductor();
// 阿迪达斯生产线产出球鞋
Shoes *adidasShoes = adidasProducer->CreateShoes();
// 阿迪达斯球鞋广喊起
adidasShoes->Show();
// 释放资源
delete adidasShoes;
delete adidasProducer;
return 0;
}
3. 抽象工程模式
场景类比:鞋厂为了扩大了业务,不仅只生产鞋子,把运动品牌的衣服也一起生产了。
3.1 UML图
3.2 具体代码实现
抽象工厂模式的结构组成(和工厂方法模式一样):
- 抽象工厂类:工厂方法模式的核心类,提供创建具体产品的接口,由具体工厂类实现。
- 具体工厂类:继承于抽象工厂,实现创建对应具体产品对象的方式。
- 抽象产品类:它是具体产品继承的父类(基类)。
- 具体产品类:具体工厂所创建的对象,就是此类。
/*
Clothe和Shoes,分别为衣服和鞋子的抽象产品类。
NiKeClothe和NiKeShoes,分别是耐克衣服和耐克衣服的具体产品类。
*/
#include <iostream>
using namespace std;
// 衣服基类
class Clothe{
public:
virtual void Show() = 0;
virtual ~Clothe(){}
};
class NikeClothe : public Clothe{
public:
void Show(){
std::cout << "我是耐克衣服,时尚我最在行!" << std::endl;
}
};
// 鞋子基类
class Shoes{
public:
virtual void Show() = 0;
virtual ~Shoes(){};
};
class NikeShoes : public Shoes{
public:
void Show(){
std::cout << "我是耐克球鞋,让你酷起来!" << std::endl;
}
};
// 总厂
class Factory{
public:
virtual Shoes *CreateShoes() = 0;
virtual Clothe *CreateClothe() = 0;
virtual ~Factory() {}
};
class NikeProducer: public Factory{
public:
Shoes *CreateShoes(){
return new NikeShoes();
}
Clothe *CreateClothe(){
return new NikeClothe();
}
};
int main(int argc, char *argv[]){
Factory *nike_producer = new NikeProducer();
Clothe *nike_clothe = nike_producer->CreateClothe();
Shoes *nike_shoes = nike_producer->CreateShoes();
nike_clothe->Show();
nike_shoes->Show();
delete nike_producer;
delete nike_clothe;
delete nike_shoes;
}
【参考连接】
https://zhuanlan.zhihu.com/p/83535678
https://zhuanlan.zhihu.com/p/83537599(进阶版工厂类)