(浅入浅出)小白学习c++工厂模式(入门搞懂版)

目录

1. 引入

2. 三种工厂模式

2.1 简单工厂模式

2.2 工厂方法模式

2.3 抽象工厂模式

3. 工厂模式的定义

参考资料


浅入浅出之小白学习软件设计方法之工厂模式!讲不明白算我输!

码字不易,如果觉得讲的好请不要吝啬你的一键三连!!!!!

本篇博客主要讲了软件设计方法之c++工厂模式。

声明,我也是小白,如果有错误,请指出,我们共同进步!

1. 引入

        我们先不看定义,请各位思考一个问题,我们刚入门c++的时候要创建一个对象该怎么创建?看下面伪代码。

class A {
public:
    xxxx
private:
    xxxx
};

class B {
public:
    xxxx
private:
    xxxx
};

int main() {
// 创建对象a
A a;

// 创建对象b
B b;
}

        现在是创建了两个类的对象,那如果有很多类呢?如果项目中需要创建很多对象呢?所以,工厂模式就提供了一种创建对象的方法。我的理解就是把创建对象的过程放到一个工厂类里面去,这个工厂类就相当于一个工厂一样,专门去产生(创建)一个个的产品(对象)。

2. 三种工厂模式

        我们还是不看定义,接下来我将采用UML类图加代码的形式讲述工厂模式的三种模式,分别是简单工厂模式、工厂方法模式、抽象工厂模式。

2.1 简单工厂模式

  • 场景:假如有一个制造车的工厂,要造SUV, 跑车,MPV三种车。
  • UML图如下所示

  •  根据UML图看如下代码
#include <iostream>

// 汽车抽象类
class Cars
{
public:
    virtual ~Cars() {} // 虚析构函数,确保正确调用派生类的析构函数
    virtual void cars_info() = 0; // 纯虚函数,要求派生类实现
};

// SUV汽车
class SUVCars : public Cars
{
public:
    void cars_info() override
    {
        std::cout << "我是SUV汽车,我的特点是:空间大,适合家庭出行" << std::endl;
    }
};

// 运动型汽车
class SportCars : public Cars
{
public:
    void cars_info() override
    {
        std::cout << "我是运动型汽车,我的特点是:速度快,外观时尚" << std::endl;
    }
};

// MPV汽车
class MPVCars : public Cars
{
public:
    void cars_info() override
    {
        std::cout << "我是MPV汽车,我的特点是:多功能,适合多人出行" << std::endl;
    }
};

// 简单工厂类
class CarsFactory
{
public:
    enum CarsType
    {
        SUV,
        SPORT,
        MPV
    };

    static Cars* create_cars(CarsType type)
    {
        switch (type)
        {
        case SUV:
            return new SUVCars();
        case SPORT:
            return new SportCars();
        case MPV:
            return new MPVCars();
        default:
            return nullptr;
        }
    }
};

int main()
{
    // 创建SUV汽车
    Cars* suv = CarsFactory::create_cars(CarsFactory::SUV);
    suv->cars_info();
    delete suv;

    // 创建运动型汽车
    Cars* sport = CarsFactory::create_cars(CarsFactory::SPORT);
    sport->cars_info();
    delete sport;

    // 创建MPV汽车
    Cars* mpv = CarsFactory::create_cars(CarsFactory::MPV);
    mpv->cars_info();
    delete mpv;

    return 0;
}

        是不是看的一头雾水,别慌我来为你逐个解释,首先既然工厂模式是用一个工厂类去创建其他的对象,我们肯定需要一个工厂类(Carsfactory),那么如何创建呢?我们只需要封装一个creat_cars函数,只要给这个函数一个参数,就可以根据这个参数创建不同的对象。

// 简单工厂类
class CarsFactory
{
public:
    enum CarsType
    {
        SUV,
        SPORT,
        MPV
    };

    static Cars* create_cars(CarsType type)
    {
        switch (type)
        {
        case SUV:
            return new SUVCars();
        case SPORT:
            return new SportCars();
        case MPV:
            return new MPVCars();
        default:
            return nullptr;
        }
    }
};

        那么既然创建对象,肯定要有相应的类,所以我们定义了SUVCars, SportCars, MPVCars。

// SUV汽车
class SUVCars : public Cars
{
public:
    void cars_info() override
    {
        std::cout << "我是SUV汽车,我的特点是:空间大,适合家庭出行" << std::endl;
    }
};

// 运动型汽车
class SportCars : public Cars
{
public:
    void cars_info() override
    {
        std::cout << "我是运动型汽车,我的特点是:速度快,外观时尚" << std::endl;
    }
};

// MPV汽车
class MPVCars : public Cars
{
public:
    void cars_info() override
    {
        std::cout << "我是MPV汽车,我的特点是:多功能,适合多人出行" << std::endl;
    }
};

         读到这里可能还有小白有疑问,那为什么还要继承抽象类(Cars)呢,直接通过工厂类(Carsfactory)创建对象不就好了,非也。

        这里之所以继承抽象类(Cars),首先可以通过基类指针或引用来操作不同类型的派生类对象。在这个例子中,我们可以通过Cars*指针来调用cars_info方法,而不需要关心具体的汽车类型。这使得代码更加灵活和可扩展。

        基类Cars使得工厂类CarsFactory可以返回不同类型的汽车对象,而不需要知道具体的汽车类型。工厂类只需要返回基类指针,这使得工厂类的实现更加简洁和通用。

// 汽车抽象类
class Cars
{
public:
    virtual ~Cars() {} // 虚析构函数,确保正确调用派生类的析构函数
    virtual void cars_info() = 0; // 纯虚函数,要求派生类实现
};

        然后再看main函数,估计就会恍然大悟。

int main()
{
    // 创建SUV汽车
    Cars* suv = CarsFactory::create_cars(CarsFactory::SUV);
    suv->cars_info();
    delete suv;

    // 创建运动型汽车
    Cars* sport = CarsFactory::create_cars(CarsFactory::SPORT);
    sport->cars_info();
    delete sport;

    // 创建MPV汽车
    Cars* mpv = CarsFactory::create_cars(CarsFactory::MPV);
    mpv->cars_info();
    delete mpv;

    return 0;
}
  • 看懂了UML图和代码之后,我们来看简单工厂模式的结构组成

        抽象产品类: 定义了产品的接口,每个具体产品都要实现这个接口。例如,在我们的例子中,Cars 是抽象产品。

        具体产品类: 实现了抽象产品接口的具体类。例如,SUVCarsSportCarsMPVCars 是 Cars 的具体产品。

        工厂类: 核心类,包含一个方法,根据传入的参数决定创建哪种类型的对象。例如,CarsFactory 是工厂类,它声明了 create_cars 方法。

2.2 工厂方法模式

  • 简单工厂模式的问题:

        有了上面对简单工厂的理解,试想这样一种情景:当我们想要添加新的产品类,我们需要直接修改工厂类(CarsFactory),这显然违背了开闭原则(对扩展开放,对修改关闭)。那该怎么办?

        我们可以从工厂划分出子工厂,把创建对象的任务交给子工厂不就行了!直接看UML图和代码。

  • UML图如下所示

  • 根据UML图看如下代码
#include <iostream>

// 汽车抽象类
class Cars
{
public:
    virtual ~Cars() {} // 虚析构函数,确保正确调用派生类的析构函数
    virtual void cars_info() = 0; // 纯虚函数,要求派生类实现
};

// SUV汽车
class SUVCars : public Cars
{
public:
    void cars_info() override
    {
        std::cout << "我是SUV汽车,我的特点是:空间大,适合家庭出行" << std::endl;
    }
};

// 运动型汽车
class SportCars : public Cars
{
public:
    void cars_info() override
    {
        std::cout << "我是运动型汽车,我的特点是:速度快,外观时尚" << std::endl;
    }
};

// MPV汽车
class MPVCars : public Cars
{
public:
    void cars_info() override
    {
        std::cout << "我是MPV汽车,我的特点是:多功能,适合多人出行" << std::endl;
    }
};

// 抽象工厂类
class CarsFactory
{
public:
    virtual ~CarsFactory() {}
    virtual Cars* create_cars() = 0; // 纯虚函数,要求派生类实现
};

// SUV汽车工厂
class SUVCarsFactory : public CarsFactory
{
public:
    Cars* create_cars() override
    {
        return new SUVCars();
    }
};

// 运动型汽车工厂
class SportCarsFactory : public CarsFactory
{
public:
    Cars* create_cars() override
    {
        return new SportCars();
    }
};

// MPV汽车工厂
class MPVCarsFactory : public CarsFactory
{
public:
    Cars* create_cars() override
    {
        return new MPVCars();
    }
};

int main()
{
    // 创建SUV汽车
    CarsFactory* suvFactory = new SUVCarsFactory();
    Cars* suv = suvFactory->create_cars();
    suv->cars_info();
    delete suv;
    delete suvFactory;

    // 创建运动型汽车
    CarsFactory* sportFactory = new SportCarsFactory();
    Cars* sport = sportFactory->create_cars();
    sport->cars_info();
    delete sport;
    delete sportFactory;

    // 创建MPV汽车
    CarsFactory* mpvFactory = new MPVCarsFactory();
    Cars* mpv = mpvFactory->create_cars();
    mpv->cars_info();
    delete mpv;
    delete mpvFactory;

    return 0;
}

我想通过我上面的讲解,这里不用细讲,也能看懂了吧?总结一句话就是,具体产品对象的创建用具体的工厂子类完成。

  • 再看工厂方法模式的结构,一目了然

        抽象产品类: 定义了产品的接口,每个具体产品都要实现这个接口。例如,在我们的例子中,Cars 是抽象产品。

        具体产品类: 实现了抽象产品接口的具体类。例如,SUVCarsSportCarsMPVCars 是 Cars 的具体产品。

        抽象工厂类: 声明了一个创建产品的方法。例如,CarsFactory 是抽象工厂,它声明了 create_cars 方法。

        具体工厂类: 实现了抽象工厂接口,负责创建具体产品的实例。例如,SUVCarsFactorySportCarsFactoryMPVCarsFactory 是具体工厂,它们实现了 create_cars 方法,分别创建相应的具体产品。

2.3 抽象工厂模式

        看懂了工厂方法模式,有时候这个工厂啊不仅仅生产一种产品,比如SUV工厂(SUVFactory),它除了产生SUV汽车产品(SUVCars),它有可能还需要生产SUV轮胎,SUV玻璃等等。这就是抽象工厂的内涵,话不多说,这次我相信直接看UML和代码就能看懂。

  • UML图如下所示

  • 根据UML图看代码(我建议直接从main函数开始看)
#include <iostream>

// 汽车抽象类
class Cars
{
public:
    virtual ~Cars() {} // 虚析构函数,确保正确调用派生类的析构函数
    virtual void cars_info() = 0; // 纯虚函数,要求派生类实现
};

// 轮胎抽象类
class Tires
{
public:
    virtual ~Tires() {}
    virtual void tire_info() = 0;
};

// SUV汽车
class SUVCars : public Cars
{
public:
    void cars_info() override
    {
        std::cout << "我是SUV汽车,我的特点是:空间大,适合家庭出行" << std::endl;
    }
};

// SUV轮胎
class SUVTires : public Tires
{
public:
    void tire_info() override
    {
        std::cout << "我是SUV轮胎,适合各种地形" << std::endl;
    }
};

// 运动型汽车
class SportCars : public Cars
{
public:
    void cars_info() override
    {
        std::cout << "我是运动型汽车,我的特点是:速度快,外观时尚" << std::endl;
    }
};

// 运动型轮胎
class SportTires : public Tires
{
public:
    void tire_info() override
    {
        std::cout << "我是运动型轮胎,适合高速行驶" << std::endl;
    }
};

// MPV汽车
class MPVCars : public Cars
{
public:
    void cars_info() override
    {
        std::cout << "我是MPV汽车,我的特点是:多功能,适合多人出行" << std::endl;
    }
};

// MPV轮胎
class MPVTires : public Tires
{
public:
    void tire_info() override
    {
        std::cout << "我是MPV轮胎,适合长途旅行" << std::endl;
    }
};

// 抽象工厂类
class CarsFactory
{
public:
    virtual ~CarsFactory() {}
    virtual Cars* create_cars() = 0; // 纯虚函数,要求派生类实现
    virtual Tires* create_tires() = 0; // 纯虚函数,要求派生类实现
};

// SUV工厂
class SUVCarsFactory : public CarsFactory
{
public:
    Cars* create_cars() override
    {
        return new SUVCars();
    }

    Tires* create_tires() override
    {
        return new SUVTires();
    }
};

// 运动型汽车工厂
class SportCarsFactory : public CarsFactory
{
public:
    Cars* create_cars() override
    {
        return new SportCars();
    }

    Tires* create_tires() override
    {
        return new SportTires();
    }
};

// MPV工厂
class MPVCarsFactory : public CarsFactory
{
public:
    Cars* create_cars() override
    {
        return new MPVCars();
    }

    Tires* create_tires() override
    {
        return new MPVTires();
    }
};

int main()
{
    // 创建SUV汽车和轮胎
    CarsFactory* suvFactory = new SUVCarsFactory();
    Cars* suv = suvFactory->create_cars();
    Tires* suvTires = suvFactory->create_tires();
    suv->cars_info();
    suvTires->tire_info();
    delete suv;
    delete suvTires;
    delete suvFactory;

    // 创建运动型汽车和轮胎
    CarsFactory* sportFactory = new SportCarsFactory();
    Cars* sport = sportFactory->create_cars();
    Tires* sportTires = sportFactory->create_tires();
    sport->cars_info();
    sportTires->tire_info();
    delete sport;
    delete sportTires;
    delete sportFactory;

    // 创建MPV汽车和轮胎
    CarsFactory* mpvFactory = new MPVCarsFactory();
    Cars* mpv = mpvFactory->create_cars();
    Tires* mpvTires = mpvFactory->create_tires();
    mpv->cars_info();
    mpvTires->tire_info();
    delete mpv;
    delete mpvTires;
    delete mpvFactory;

    return 0;
}

        是不是看到这么宽的UML图,和这么长的代码就感觉不好理解。有什么不好理解的,直接看main函数,你会发现其实SUV工厂(SUVFactory)造SUV车产品(SUVCars)和SUV轮胎产品(SUVTires)

        总结就是一个具体工厂类,可以造多个同系列的产品。

        还难吗??

  • 抽象工厂模式的结构

        抽象产品类:定义了产品的接口,每个具体产品都要实现这个接口。例如,在我们的例子中,Cars 和 Tires 是抽象产品。

        具体产品类:实现了抽象产品接口的具体类。例如,SUVCarsSportCarsMPVCars 是 Cars 的具体产品,SUVTiresSportTiresMPVTires 是 Tires 的具体产品

        抽象工厂类:声明了一组创建产品的方法,每个方法对应一个抽象产品。例如,CarsFactory 是抽象工厂,它声明了 create_cars 和 create_tires 方法。

        具体工厂类:实现了抽象工厂接口,负责创建具体产品的实例。例如,SUVCarsFactorySportCarsFactoryMPVCarsFactory 是具体工厂,它们实现了 create_cars 和 create_tires 方法,分别创建相应的具体产品。

3. 工厂模式的定义

        有了上面的讲解,我们现在看工厂模式的定义,是不是就很清楚了。

        工厂模式(Factory Pattern)是一种创建型设计模式,它提供了一种创建对象的方式,使得创建对象的过程与使用对象的过程分离。工厂模式的主要目的是将对象的创建过程封装在工厂类中,客户端代码只需要关心从工厂获取对象的过程,而不需要了解对象的创建细节。

参考资料

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值