0
点赞
收藏
分享

微信扫一扫

1. qml的基础入门篇-及学习思路大纲

waaagh 04-10 20:01 阅读 0

设计模式——工厂模式

我们今天来接着学习工厂模式,如果还没有看过上一篇简单工厂模式的小伙伴可以点击这里:

什么叫工厂模式

工厂模式是一种设计模式,主要用于解决对象创建的问题,它提供了一个接口用于创建对象,但是让子类决定实例化哪一个类。工厂模式的核心思想是将对象的创建过程封装起来,使客户端不需要知道具体的产品类,只需关心接口即可。这样可以极大地减少代码间的耦合度,增强系统的灵活性和可扩展性。

根据抽象程度和创建对象的复杂度,工厂模式可以细分为以下几种:

通过使用工厂模式,你可以:

其中简单工厂模式已经在上篇提及到了,我们来看看这三种工厂模式的区别:

三种工厂模式的区别

让我们用生活中的例子来通俗地解释这三种工厂模式:

在代码中,简单工厂就是一个静态方法或类,接收一个参数(比如食物类型),然后根据这个参数创建并返回一个相应的产品对象。

在代码中,工厂方法模式定义了一个抽象工厂接口,包含一个创建产品的方法,具体的子类会实现这个方法来创建特定的产品对象。

在代码中,抽象工厂模式定义了一个接口或抽象类,这个接口可以生成一族相关的产品对象,比如一个餐厅抽象工厂可以创建主食工厂、饮料工厂和甜品工厂,每一种工厂又能创建具体的产品。

总结一下,简单工厂模式是集中处理对象创建,工厂方法模式是将对象创建的权利委托给了子类,而抽象工厂模式则关注于创建一组相关的产品对象,它们各有侧重点,适用于不同的应用场景。

工厂方法模式

下面这个例子可以帮助我们了解工厂方法模式:

首先工厂方法会有四个部分:抽象任务+具体任务+抽象工厂+具体工厂

//抽象任务
class Task
{

};
//具体任务
//exam
class Exam : public Task
{

};

//Homework
class Homework : public Task
{

};

//video
class video : public Task
{

};

//text
class text : public Task
{

};


//ppt
class ppt : public Task
{

};

//ppt
class testpaper : public Task
{

};

//抽象工厂
class abstractFactory
{

};


//具体工厂
class realFactory : public abstractFactory
{

};

之后调用具体工厂,我们就可以对应创建相应的类:

// 客户端代码,使用抽象工厂
void configureLesson(const std::vector<std::string>& tasksTypes, abstractFactory& factory)
{
    std::vector<std::unique_ptr<Task>> lessonTasks;
    for (const auto& type : tasksTypes)
    {
        auto task = factory.createTask(type);
        lessonTasks.push_back(std::move(task));
    }

    for(int i = 0; i < lessonTasks.size(); i++)
    {
        std::cout<<lessonTasks[i]->getTask_name()<<std::endl;
        lessonTasks[i]->execte();
        std::cout<<std::endl;
    }
    // 分配任务给学生,执行任务等操作...
}

完整代码如下:

// 导入必要的头文件
#pragma once
#include<iostream>
#include<cstring>
#include<memory>
#include<vector>

// 抽象任务接口类,定义了任务的基本属性和行为
class Task
{
public:
    // 虚拟析构函数,确保派生类能够正确析构
    virtual ~Task() {};

    // 纯虚函数,用于获取任务名称,所有派生类必须重写此方法
    virtual std::string getTask_name() const = 0;

    // 纯虚函数,用于执行任务,所有派生类必须重写此方法
    virtual void execte() const = 0;
};

// 具体任务类,分别代表不同的任务类型
// Exam(考试任务)
class Exam : public Task
{
public:
    std::string getTask_name() const override
    {
        return "Exam";
    }

    void execte() const override
    {
        std::cout << "doing exam" << std::endl;
    }
};

// Homework(家庭作业任务)
class Homework : public Task
{
public:
    std::string getTask_name() const override
    {
        return "Homework";
    }

    void execte() const override
    {
        std::cout << "doing Homework" << std::endl;
    }
};

// video(视频学习任务)
class video : public Task
{
public:
    std::string getTask_name() const override
    {
        return "video";
    }

    void execte() const override
    {
        std::cout << "doing video" << std::endl;
    }
};

// text(文本阅读任务)
class text : public Task
{
public:
    std::string getTask_name() const override
    {
        return "text";
    }

    void execte() const override
    {
        std::cout << "doing text" << std::endl;
    }
};

// ppt(演示文稿任务)
class ppt : public Task
{
public:
    std::string getTask_name() const override
    {
        return "ppt";
    }

    void execte() const override
    {
        std::cout << "doing ppt" << std::endl;
    }
};

// testpaper(试卷任务)
class testpaper : public Task
{
public:
    std::string getTask_name() const override
    {
        return "testpaper";
    }

    void execte() const override
    {
        std::cout << "doing testpaper" << std::endl;
    }
};

// 抽象工厂接口,定义了创建任务对象的方法
class abstractFactory
{
public:
    virtual ~abstractFactory() {};

    // 纯虚函数,根据传入的字符串类型创建对应的任务对象
    virtual std::unique_ptr<Task> createTask(const std::string& name) const = 0;
};

// 具体工厂类,实现了抽象工厂接口,根据不同类型创建具体任务对象
class realFactory : public abstractFactory
{
public:
    std::unique_ptr<Task> createTask(const std::string& type) const override
    {
        if (type == "Exam")
        {
            return std::make_unique<Exam>();
        }
        else if (type == "Homework")
        {
            return std::make_unique<Homework>();
        }
        else if (type == "video")
        {
            return std::make_unique<video>();
        }
        else
        {
            // 如果传入的任务类型不支持,则抛出异常
            throw std::invalid_argument("Unsupported task type.");
        }
    }
};

// 客户端代码,使用抽象工厂配置课程任务
void configureLesson(const std::vector<std::string>& tasksTypes, abstractFactory& factory)
{
    // 创建存放任务智能指针的容器
    std::vector<std::unique_ptr<Task>> lessonTasks;

    // 根据任务类型列表,通过工厂创建任务对象并加入容器
    for (const auto& type : tasksTypes)
    {
        auto task = factory.createTask(type);
        lessonTasks.push_back(std::move(task)); // 使用移动语义存储任务
    }

    // 执行并展示所有任务
    for (int i = 0; i < lessonTasks.size(); i++)
    {
        std::cout << lessonTasks[i]->getTask_name() << std::endl;
        lessonTasks[i]->execte();
        std::cout << std::endl;
    }

    // 此处省略了分配任务给学生的逻辑及其他操作...
}

在这里插入图片描述

这段代码定义了一个抽象任务接口 Task,并创建了多个具体任务类,同时使用了抽象工厂模式来根据字符串类型动态创建任务对象。在客户端代码中,通过抽象工厂创建了一系列任务,并执行了这些任务。这样做的好处是可以方便地扩展任务类型,同时保持客户端代码的简洁和独立于具体任务实现。

举报

相关推荐

0 条评论