前言:
? ? ? ? 在学习工厂方法模式之前,你需要知道什么事简单工厂方法模式,如果你还不了解简单工厂,请先阅读这篇文章:简单工厂模式?之后再继续学习工厂方法模式。
工厂方法模式是在简单工厂模式基础上进行的扩展,为了解决简单工厂模式的中存在的问题:工厂一旦不能正常运行,将会影响到整个系统;违背了“开放-关闭原则”;工厂类的静态方法不能被重写。因此衍生出了工厂方法模式。
一、什么事工厂方法模式:
????????工厂方法模式又称为多态工厂模式、虚拟构造器模式。通过在工厂父类中创建公共的产品对象创建接口,而子类中负责生产具体的产品对象。
????????工厂方法模式主要是为了将类的实例化过程(具体产品的创建)延迟到工厂子类(具体工厂)中完成,即由子类来决定应该实例化哪一个类。这一点主要是解决了简单工厂模式中在工程类里面通过传递参数来决定具体产品的实例化问题,解决了简单工厂模式带来的违背了“开放-关闭原则”。
? ? ? ? 工厂方法模式吧具体产品的创建推迟到了工厂类的子类(具体工厂)中,此时的工厂类(父类)不再负责所有产品的创建,而是给出了创建产品的公共接口,子类必须重写这一公共接口,这样工厂方法模式中新增加产品的时候就会修改任何工厂的逻辑,而是添加新的工厂子类,这样更加符合“开放-关闭原则”。
二、原理:
? ? ? ? 工厂模式主要由以下四个模块组成:抽象产品、抽象工厂、具体产品、具体工厂。抽象产品是具体产品的父类,提供了创建具体产品的公共接口;抽象工厂是具体工厂的父类,提供了具体工厂创建的公共接口;具体产品是抽象产品的子类,是具体工厂类创建的目标类,用于生产具体的产品;具体工厂是抽象工厂的子类,可以被外界所调用,用于生产具体的产品对象。
1、使用步骤:
(1)创建抽象产品类,定义具体产品的公共接口。
(2)创建抽象工厂类,提供具体工厂创建的公共接口。
(3)创建具体产品类,并且定义生产的具体产品。
(4)创建具体工厂类,定义创建具体产品的实例化方法,并对外开发。
(5)外界调用具体工厂类的方法,从而创建出具体产品的实例。
三、示例:
????????本人家里有一个玩具厂,目前涉及到的业务包括玩具枪(toyGun)、布娃娃(ragDoll)、玩具车(toyCar),以此为使用场景,通过简单工厂模式来实现。
1、创建抽象产品:
// 抽象产品类
class AbstractProduct
{
public:
virtual ~AbstractProduct();
// 具体产品的公共接口
virtual void createTheProduct();
};
2、创建抽象工厂:
// 抽象工厂类
class AbstractFactory
{
public:
virtual ~AbstractFactory();
// 具体工厂创建的公共接口
virtual void factoryMakeProduct();
};
3、创建具体产品类:
// 具体产品类
// 玩具枪
class ToyGunProduct : public AbstractProduct
{
public:
// 具体产品的生产接口:生产玩具枪
void createTheProduct() override;
};
// 布娃娃
class RagDollProduct : public AbstractProduct
{
public:
// 具体产品的生产接口:生产布娃娃
void createTheProduct() override;
};
// 玩具车
class ToyCarProduct : public AbstractProduct
{
public:
// 具体产品的生产接口:生产玩具车
void createTheProduct() override;
};
4、创建具体工厂类:
class ToyGunFactory : public AbstractFactory
{
public:
// 具体工厂生产具体产品
void factoryMakeProduct() override;
};
// 具体工厂:生产布娃娃
class RagDollFactory :public AbstractFactory
{
public:
void factoryMakeProduct() override;
};
// 具体工厂:生产玩具枪
class ToyCarFactory : public AbstractFactory
{
public:
void factoryMakeProduct();
};
5、通过具体工厂创建具体产品对象:
int main()
{
// 外界通过调用具体工厂类的方法,从而创建出不同的产品实例
// 玩具枪
auto factoryA = new ToyGunFactory();
factoryA->factoryMakeProduct();
// 布娃娃
auto factoryB = new RagDollFactory();
factoryB->factoryMakeProduct();
// 玩具车
auto factoryC = new ToyCarFactory();
factoryC->factoryMakeProduct();
return 0;
}
四、优缺点对比:
1、优点:
- 工厂方法模式根据符合开闭原则:每新增一种产品的时候,只需要增加相应的具体产品类和对应的工厂子类即可。
- 更加符合C++的封装特性,每一个具体的工厂只负责创建对应的独立产品。
- 不使用静态方法,可以形成基于继承的等级结构。
? ? ? ? 工厂方法模式是在简单工厂模式的基础上进行了抽象和拓展,在保留了简单工厂的优点基础上,然扩展变得更加的简单,继承变得更加的具有可行性,体现了C++封装、继承、多态的特性。
2、缺点:
- 添加新产品的时候,除了增加新产品的具体类之外,还要增加生产新产品的具体工厂。在一定的程度上增加了系统的复杂度,同时有更多的类需要进行编译,带来了额外的系统开销。
- 一个具体工厂只能创建一种具体产品
|