工厂模式是一种创建型设计模式,用于创建对象而无需指定具体创建的类。它通过提供一个共同的接口来创建对象,但允许子类决定实例化哪个类。工厂模式的主要目的是将对象的创建和使用分离,以便代码更容易扩展和维护。
关键组成部分:
-
工厂接口(Factory Interface):
- 定义一个创建对象的接口,通常是一个抽象类或接口。工厂接口可能包含多个工厂方法,每个方法用于创建不同类型的对象。
-
具体工厂(Concrete Factory):
- 实现工厂接口,负责创建具体的产品对象。每个具体工厂类对应于创建一类具体产品。
-
产品接口(Product Interface):
- 定义工厂方法创建的对象的接口,通常是一个抽象类或接口。具体产品类实现这个接口。
-
具体产品(Concrete Product):
- 实现产品接口定义的具体对象。工厂方法将创建这些具体产品的实例。
工作原理:
工厂模式通过引入工厂类来代替在客户端代码中直接使用 new
关键字来创建对象。客户端代码通过调用工厂方法来创建所需的对象,而无需了解具体的对象类型。这种方式使得系统更具灵活性,因为可以随时更改或扩展创建对象的方式,而无需修改客户端代码。
优点:
- 解耦合:客户端代码与创建对象的具体实现分离,降低了耦合度。
- 扩展性:易于扩展以支持新的产品类型,只需添加新的具体工厂和产品类即可,无需修改现有代码。
- 管理复杂对象创建:可以封装复杂的对象创建逻辑,使客户端代码更加简洁和易于维护。
适用场景:
- 当一个类不知道它所需要的对象的类时。
- 当一个类希望由它的子类来指定所创建的对象时。
- 当类将创建对象的职责委托给多个帮助子类中的某一个,并且希望动态决定所创建对象时。
工厂模式可以根据其实现方式和结构的不同,分为三种主要的分类:简单工厂模式、工厂方法模式和抽象工厂模式。
简单工厂模式
简单工厂模式是一种创建型设计模式,它提供了一个统一的接口来创建不同类型的对象,而无需暴露对象创建的具体逻辑。在简单工厂模式中,有一个工厂类负责根据客户端的需求创建相应的产品对象。
基本结构:
产品接口(Product Interface):定义了工厂方法所创建的对象的接口。
具体产品类(Concrete Products):实现了产品接口的具体产品类。
工厂类(Factory Class):包含一个工厂方法,根据客户端的需求创建并返回具体产品类的实例。
应用场景
解决接口选择问题
//抽象汽车
class AbstractCar
{
public:
virtual void ShowCarName = 0;
};
//具体产品的汽车继承抽象汽车类,并对其方法进行重写
//凯美瑞
class Camry: public AbstractCar
{
void ShowCarName override()
{
cont<<"Camry Car"<< endl;
}
};
//迈腾
class Magotan: public AbstractCar
{
void ShowCarName override()
{
cout<<"Magotan Car"<<endl;
}
};
//通过传递过来的参数来确定需要生产那种汽车
//汽车工厂
class CarFactory
{
public:
static AbstractCar* CreateCarFunc(string cname)
{
if(cname == "Camary")
{
return new Camary;
}else if(cname == "Magotan")
{
return new Magotan;
}
else
return nullptr;
}
}
int main()
{
//创建工厂
carFactory *fty = new carFactory;
//创建汽车
AbstractCar* Acar;
//指定工厂需要创建的汽车
Acar = fty->CreateCarFunc("Magotan");//获取指定车对象
Acar->showCarName;
delete Acar;
Acar = fty->CreateCarFunc("Camry");//获取指定车对象
Acar->showCarName;
delete Acar;
return 0;
}
抽象工厂模式
抽象工厂模式(Abstract Factory Pattern)是围绕一个超级工厂创建其他工厂。该超级工厂又称为其他工厂的工厂。这种类型的设计模式属于创建型模式,它提供了一种创建对象的最佳方式。
在抽象工厂模式中,接口是负责创建一个相关对象的工厂,不需要显式指定它们的类。每个生成的工厂都能按照工厂模式提供对象。
工厂模式中的每一种形态都是针对一定问题的解决方案,工厂方法针对的是多个产品系列结构,而抽象工厂模式针对的是多个产品族结构,一个产品族内有多个产品系列。
在抽象工厂模式中,客户端不再负责对象的创建,而是把这个责任丢给具体的工厂类,客户端只负责对对象的调用,从而明确各个类的职责
抽象工厂四种角色
- 抽象工厂角色
- 具体工厂角色
- 抽象产品角色
- 具体产品角色
代码示例
#include<iostream>
using namespace std;
//抽象西瓜
class AbstractWatermelon()
{
public:
virtual void PrintName() = 0;
AbstractWatermelon()
{
cout<<"抽象西瓜的构造函数"<<endl;
}
~AbstractWatermelon()
{
cout<<"抽象西瓜的析构函数"<<endl;
}
};
//抽象橘子
class AbstractOrange()
{
public:
virtual void PrintName() = 0;
AbstractOrange()
{
cout<<"抽象橘子的构造函数"<<endl;
}
~AbstractOrange()
{
cout<<"抽象橘子的析构函数"<<endl;
}
};
//中国西瓜
class ChineseWatermelon: public AbstractWatermelon()
{
public:
void PrintName () override
{
cout<<"中国西瓜"<<endl;
}
ChineseWatermelon()
{
cout<<"中国西瓜的构造函数"<<endl;
}
~ChineseWatermelon()
{
cout<<"中国西瓜的析构函数 "<<endl;
}
};
//中国橘子
class ChineseOrange: public AbstractOrange
{
public:
void PrintName() override
{
cout<<"抽象中国橘子"<<endl;
}
ChineseOrange()
{
cout<<"中国橘子构造函数"<<endl;
}
~ChineseOrange()
{
cout<<"中国橘子析构函数"<<endl;
}
};
//埃及西瓜
class EgyptWatermelon: public AbstractWatermelon()
{
public:
void PrintName () override
{
cout<<"埃及西瓜"<<endl;
}
EgyptWatermelon()
{
cout<<"埃及西瓜的构造函数"<<endl;
}
~EgyptWatermelon()
{
cout<<"埃及西瓜的析构函数 "<<endl;
}
};
//埃及橘子
class EgyptOrange: public AbstractOrange
{
public:
void PrintName() override
{
cout<<"埃及橘子"<<endl;
}
EgyptOrange()
{
cout<<"埃及橘子构造函数"<<endl;
}
~EgyptOrange()
{
cout<<"埃及橘子析构函数"<<endl;
}
};
//抽象工厂 主要针对产品转换
class AbstractFactory
{
public:
virtual AbstractWatermelon* CreateWatermelon() = 0;
virtual AbstractOrange* CreateOrange() = 0;
AbstractFactory()
{
cout<<"抽象工厂构造函数"<<endl;
}
~AbstractFactory()
{
cout<<"抽象工厂析构函数"<<endl;
}
};
//中国工厂
class ChinaFactory: public AbstractFactory
{
public:
AbstractWatermelon* CreateWatermelon() override
{
return new ChineseWatermelon;
}
AbstractOrange* CreateOrange() override
{
return new ChineseOrange;
}
ChinaFactory(){}
~ChinaFactory(){}
};
//埃及工厂
class EgyptFactory: public AbstractFactory
{
public:
AbstractWatermelon* CreateWatermelon() override
{
return new EgyptWatermelon;
}
AbstractOrange* CreateOrange() override
{
return new EgyptOrange;
}
EgyptFactory(){}
~EgyptFactory(){}
};
int main()
{
//中国工厂
AbstractFactory* cfactory = new ChinaFactory;
AbstractWatermelon *cwatermelon = cfactory->CreateWatermelon();
AbstractOrange *corange = cfactory->CreateOrange();
cwatermelon->PrintName();
corange->PrintName();
delete corange;
corange = nullptr;
delete cwatermelon;
cwatermelon = nullptr;
delete cfactory;
cfactory = nullptr;
return 0;
}