前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >【C++】设计模式:工厂模式

【C++】设计模式:工厂模式

作者头像
DevFrank
发布2024-07-24 15:20:10
810
发布2024-07-24 15:20:10
举报
文章被收录于专栏:C++开发学习交流

1. 工厂模式

工厂模式属于创建者模式,提供了一种创建对象的最佳方式。

工厂模式的实现方式有简单工厂模式、工厂方法模式、抽象工厂模式,每个实现方式都存在优和劣。

简单工厂模式与工厂模式的结构组成是:

代码语言:javascript
复制
1. 工厂类:工厂模式的核心类,会定义一个用于创建指定的具体实例对象的接口。(可分为抽象工厂和具体工厂)
2. 抽象产品类:是具体产品类的继承的父类或实现的接口。
3. 具体产品类:工厂类所创建的对象就是此具体产品实例。

以汽车厂为例:

Cars为汽车的抽象类(基类),接口函数为Show(),用于显示文本。

Benzi、Audi、Bmw为具体汽车品牌的类,它们都继承于Cars抽象类。

代码语言:javascript
复制
// 汽车抽象类
class Cars
{
public:
    virtual ~Cars() {}
    virtual void Show() = 0;
};

// 奔驰
class Benzi: public Cars
{
public:
    void Show()
    {
        std::cout << "我是Benzi" << std::endl;
    }
};

// 奥迪
class Audi: public Cars
{
public:
    void Show()
    {
        std::cout << "我是Audi" << std::endl;
    }
};

// 宝马
class Bmw: public Cars
{
public:
    void Show()
    {
        std::cout << "我是Bmw" << std::endl;
    }
};

CarsFactory为工厂类,类里实现根据汽车类型创建对应产品对象的CreateCars(CARS_TYPE type)函数。

代码语言:javascript
复制
enum CARS_TYPE
{
    BENZI,
    AUDI,
    BMW
};

// 总车厂
class CarsFactory
{
public:
    // 根据鞋子类型创建对应的鞋子对象
    Cars *CreateCars(CARS_TYPE type)
    {
        switch (type)
        {
        case BENZI:
            return new Benzi();
            break;
        case AUDI:
            return new Audi();
            break;
        case BMW:
            return new Bmw();
            break;
        default:
            return NULL;
            break;
        }
    }
};

main函数,先是构造了工厂对象,然后创建指定类型的具体产品对象,然后输出对应文本。因为采用的是new的方式创建了对象,用完了要通过delete 释放资源资源。

代码语言:javascript
复制
int main()
{
    // 构造工厂对象
    CarsFactory carsFactory;

    // 从工厂对象创建benzi对象
    Cars *pBenzi = carsFactory.CreateCars(BENZI);
    if (pBenzi != NULL)
    {
        pBenzi->Show();

        // 释放资源
        delete pBenzi;
        pBenzi = NULL;
    }

    // 从工厂对象创建audi对象
    Cars *pAudi = carsFactory.CreateCars(AUDI);
    if (pAudi != NULL)
    {
        pAudi ->Show();

        // 释放资源
        delete pAudi ;
        pAudi = NULL;
    }

    // 从工厂对象创建bmw对象
    Cars *pBmw = carsFactory.CreateCars(BMW);
    if (pBmw != NULL)
    {
        pBmw ->Show();

        // 释放资源
        delete pBmw ;
        pBmw  = NULL;
    }

    return 0;
}

2. 工厂方法模式

简单工厂模式存在最大的问题是违背了“开闭原则”,每当增加新的产品时,需要修改工厂类的逻辑。为了规避这种不足,同时很好的利用简单工厂模式的优点,这里介绍工厂方法模式。

工厂方法模式:定义一个用于创建对象的接口,但是让子类决定将哪一个类实例化。工厂方法模式让一个类的实例化延迟到其子类。示例如下:

代码语言:javascript
复制
#include <iostream>
#include <string>

// 产品基类
class Product {
public:
    virtual void use() = 0;
};

// 具体产品类 A
class ConcreteProductA : public Product {
public:
    void use() override {
        std::cout << "Using ConcreteProductA" << std::endl;
    }
};

// 具体产品类 B
class ConcreteProductB : public Product {
public:
    void use() override {
        std::cout << "Using ConcreteProductB" << std::endl;
    }
};

// 工厂基类
class Factory {
public:
    virtual Product* createProduct() = 0;
};

// 具体工厂类 A
class ConcreteFactoryA : public Factory {
public:
    Product* createProduct() override {
        return new ConcreteProductA();
    }
};

// 具体工厂类 B
class ConcreteFactoryB : public Factory {
public:
    Product* createProduct() override {
        return new ConcreteProductB();
    }
};

int main() {
    // 使用具体工厂 A 创建产品 A
    Factory* factoryA = new ConcreteFactoryA();
    Product* productA = factoryA->createProduct();
    productA->use();

    // 使用具体工厂 B 创建产品 B
    Factory* factoryB = new ConcreteFactoryB();
    Product* productB = factoryB->createProduct();
    productB->use();

    delete factoryA;
    delete productA;
    delete factoryB;
    delete productB;

    return 0;
}

相较简单工厂模式,工厂方法模式更加符合开闭原则。工厂方法是使用频率最高的设计模式之一,是很多开源框架和API类库的核心模式。

3. 抽象工厂模式

汽车厂为了扩大业务,不只生产汽车了,还生产摩托车。抽象工厂模式可以创建多个工厂和多个产品族。

抽象工厂模式的组成:

代码语言:javascript
复制
1. 抽象工厂类:工厂方法模式的核心类,提供创建具体产品的接口,由具体工厂类实现。
2. 具体工厂类:继承于抽象工厂,实现创建对应具体产品对象的方式。
3. 抽象产品类:它是具体产品继承的父类(基类)。
4. 具体产品类:具体工厂所创建的对象,就是此类。

创建基类(抽象产品类):

代码语言:javascript
复制
// 汽车抽象类
class Cars
{
public:
    virtual ~Cars() {}
    virtual void Show() = 0;
};

// 奔驰
class BenziCar: public Cars
{
public:
    void Show()
    {
        std::cout << "我是Benzi car" << std::endl;
    }
};

// 摩托车抽象类
class Motors
{
public:
    virtual ~Motors() {}
    virtual void Show() = 0;
};

// 奔驰
class BenziMotor: public Motors
{
public:
    void Show()
    {
        std::cout << "我是Benzi motor" << std::endl;
    }
};

Factory为抽象工厂,提供了创建汽车CreateCars()和摩托车产品CreateMotors()对象的接口。

BenziProducer为具体工厂,实现了创建奔驰汽车和奔驰摩托车的方式。

代码语言:javascript
复制
// 总厂
class Factory
{
public:
    virtual Cars *CreateCars() = 0;
	virtual Motors *CreateMotors() = 0;
    virtual ~Factory() {}
};

// benzi生产者/生产链
class BenziProducer : public Factory
{
public:
    Cars *CreateCars()
    {
        return new BenziCar();
    }
	
	Motors *CreateMotors()
    {
        return new BenziMotor();
    }
};

main函数,构造benzi工厂对象,然后创建benzi产品族的汽车和摩托车对象。同样,对象不再使用时,需要手动释放资源。

代码语言:javascript
复制
int main()
{
    // ================ 生产Benzi流程 ==================== //
    // 生产线
    Factory *benziProducer = new BenziProducer();
    
	// 生产汽车
    Cars *benziCar = benziProducer ->CreateCars();
	// 生产摩托车
    Motors *benziMotor = benziProducer ->CreateMotors();
    
    benziCar->Show();
    benziMotor->Show();
	
    // 释放资源
    delete benziCar;
	delete benziMotor;
    delete benziProducer;

    return 0;
}

适用场景:

  • 一系列/一族产品需要被同时使用时,适合使用抽象工厂模式;
  • 产品结构稳定,设计完成之后不会向系统中新增或剔除某个产品。
本文参与 腾讯云自媒体同步曝光计划,分享自作者个人站点/博客。
原始发表:2024-03-08,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 1. 工厂模式
  • 2. 工厂方法模式
  • 3. 抽象工厂模式
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档