当前位置: 首页 > news >正文

简单工厂模式、工厂模式、抽象工厂模式(含C++代码)

一、定义

尽可能用简洁的语言描述:
(1) 简单工厂模式:
  一个工厂,多个产品,产品需要有一个接口类。工厂类根据传入的参数,动态决定应该创建哪一类产品类,用产品基类指针指向实例化的产品并返回。
(2) 工厂模式:
  多个工厂,多个产品,产品和工厂各有一个接口类。工厂和产品一一对应,一个工厂只负责生产一种产品。工厂接口类中声明一个创建产品的纯虚函数,各具体工厂类需重写该方法。
(3) 抽象工厂模式:
  多个工厂,多个产品,每类产品又分为若干子系列,工厂有一个接口类,每一类产品都有自己的接口类,一个工厂可以生产多类不同的产品。
  举例:有Food和Car两类产品,每类产品都包含2个子系列A,B,故一共FoodA、FoodB、CarA、CarB四种,有两个工厂FactoryA、FactoryB,他们都能生产A、B两类产品,只不过FactoryA只生产FoodA和CarA,FactoryB只生产FoodB和CarB。工厂接口类中需声明创建产品的纯虚函数,有多少类产品,就有几个创建产品的纯虚函数。

具体可以看第二部分的代码演示,或者第三部分的参考文献。


二、代码演示

2.1 简单工厂模式

  代码示意:

#include <iostream>
using namespace std;

/*一个工厂,多个产品,产品需要一个产品接口类,工厂根据传入参数决定创建哪种产品,
 *违反开闭原则(可以在原始代码的基础上新增代码,但不可以修改原始代码)*/

class Product {
public:
    virtual void show() = 0;
};

class ProductA : public Product {
public:
    void show() {
        cout << "this is product A" << endl;
    }
};

class ProductB : public Product {
public:
    void show() {
        cout << "this is product B" << endl;
    }
};

class Factory {
public :
    Product *createProduct(int flag) {
        Product *res = nullptr;
        if (flag == 1) {
            res = new ProductA();
        } else {
            res = new ProductB();
        }
        return res;
    }
};

int main() {
    Factory *f = new Factory();
    Product *p = f->createProduct(2);
    p->show();
    return 0;
}

  代码解释:有A、B两类产品,没有工厂前,用户需要哪类产品,就需要自己new一个产品出来,现在有了工厂,把制作产品的逻辑放到工厂类中,用户通过传入参数告诉工厂制作哪一类产品(传入参数1,表示创建产品A,传入参数2,表示创建产品B,因此工厂类中含有很多if else语句,或者switch case语句),工厂返回制作完成的产品。
  模式缺点:每新增或删除一个产品,都要修改工厂类的内部逻辑,违反开闭原则(可以在原始代码的基础上新增代码,但不可以修改原始代码逻辑)


2.2 工厂模式

  代码示意:

#include <iostream>
using namespace std;

/*多个产品、多个工厂、产品和工厂各自都需要一个接口类,一个工厂负责生产一种产品
 *每新增一类产品,就需要新创建一个工厂类*/

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

class ProductA : public Product {
public:
    void show() {
        cout << "this is product A" << endl;
    }
};

class ProductB : public Product {
public:
    void show() {
        cout << "this is product B" << endl;
    }
};

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

class FactoryA : public Factory {
public :
    Product *createProduct() {
        return new ProductA();
    }
};

class FactoryB : public Factory {
public :
    Product *createProduct() {
        return new ProductB();
    }
};

int main() {
    Factory *fa = new FactoryA();
    Factory *fb = new FactoryB();

    Product *pa = fa->createProduct();
    Product *pb = fb->createProduct();
    pa->show();
    pb->show();
    return 0;
}

  代码解释:有ProductA 、ProductA 两类产品,FactoryA 、FactoryB两个工厂,一个工厂负责生产一类产品,FactoryA 生产ProductA ,FactoryB 生产ProductB ,工厂的接口类中要定义创建产品的虚函数。
  模式缺点::每新增一类产品,就需要新创建一个工厂类。


2.3 抽象工厂模式

  代码示意:

#include <iostream>
#include <vector>
#include <string>
using namespace std;

/*多类产品、多个工厂,每类产品包含若干子系列,每个工厂可以生产多类产品
 *(工厂接口类中声明创建不同产品的方法),产品和工厂都需要接口类*/

// 第一类产品 Food
class Food {
public:
    virtual void show() = 0;
};

class FoodA : public Food {
public:
    void show() {
        cout << "this is food A" << endl;
    }
};

class FoodB : public Food {
public:
    void show() {
        cout << "this is food B" << endl;
    }
};

// 第一类产品 Car
class Car {
public:
    virtual void show() = 0;
};

class CarA : public Car {
public:
    void show() {
        cout << "this is car A" << endl;
    }
};

class CarB : public Car {
public:
    void show() {
        cout << "this is car B" << endl;
    }
};

// 工厂类
class Factory {
public :
    virtual Food *createFood() = 0;
    virtual Car *createCar() = 0;
};

class FactoryA : public Factory {
public :
    Food *createFood() {
        return new FoodA();
    }
    Car *createCar() {
        return new CarA();
    }
};

class FactoryB : public Factory {
public :
    Food *createFood() {
        return new FoodB();
    }
    Car *createCar() {
        return new CarB();
    }
};

int main() {
    Factory *fa = new FactoryA();
    fa->createFood()->show();
    fa->createCar()->show();

    Factory *fb = new FactoryB();
    fb->createFood()->show();
    fb->createCar()->show();

    return 0;
}

  代码解释:多类产品、多个工厂,每类产品包含若干子系列,每个工厂可以生产多类产品,工厂接口类中声明创建不同产品的方法),产品和工厂都需要接口类。
  对应到代码中为:有Food和Car两类产品,每类产品包含A、B两个子系列,故有4类产品:FoodA、FoodB、CarA、CarB,有两个工厂FactoryA、FactoryB,其中FactoryA负责生产Food和Car的A系列产品,FactoryB负责生产Food和Car的B系列产品。


三、参考文献

(1) https://refactoringguru.cn/design-patterns/abstract-factory/cpp/example (代码写得好)
(2) https://blog.csdn.net/linwh8/article/details/51232834 (图画得好)
(3) https://developer.aliyun.com/article/761946 (代码和文字叙述的很好)

相关文章:

  • 自动化测试之路 —— Appium输入及模拟手势
  • 使用聚类(K-means)分析方法对骑手进行分类标签定义
  • Z-Score模型的进阶版:Zeta模型
  • 从零开始配置vim(20)——模糊查询
  • 【CSAPP】现代操作系统前几章
  • React全家桶
  • 聊一聊密钥交换
  • 安装 ZooKeeper 并配置服务
  • 【时间序列】时间序列预测基本方法:移动平均(SMA,EMA,WMA)
  • 电脑重装系统开机后运行慢怎么办
  • [高性能] 关于如何高效的往本地写入视频
  • 【C++】string类
  • 一级建造师考试大纲要改版了?对2022年的考试有影响吗?
  • CSS 伪类选择器 last-child 和 last-of-type 的区别
  • string
  • 【159天】尚学堂高琪Java300集视频精华笔记(128)
  • 2017-09-12 前端日报
  • CAP理论的例子讲解
  • Git的一些常用操作
  • Java 9 被无情抛弃,Java 8 直接升级到 Java 10!!
  • JS进阶 - JS 、JS-Web-API与DOM、BOM
  • MySQL Access denied for user 'root'@'localhost' 解决方法
  • Nodejs和JavaWeb协助开发
  • Vue官网教程学习过程中值得记录的一些事情
  • Vue组件定义
  • 从地狱到天堂,Node 回调向 async/await 转变
  • 复杂数据处理
  • 更好理解的面向对象的Javascript 1 —— 动态类型和多态
  • 前端_面试
  • 如何设计一个比特币钱包服务
  • 微龛半导体获数千万Pre-A轮融资,投资方为国中创投 ...
  • 选择阿里云数据库HBase版十大理由
  • ​Linux·i2c驱动架构​
  • ​总结MySQL 的一些知识点:MySQL 选择数据库​
  • ‌内网穿透技术‌总结
  • #LLM入门|Prompt#1.8_聊天机器人_Chatbot
  • (1)(1.11) SiK Radio v2(一)
  • (C++)栈的链式存储结构(出栈、入栈、判空、遍历、销毁)(数据结构与算法)
  • (M)unity2D敌人的创建、人物属性设置,遇敌掉血
  • (Python) SOAP Web Service (HTTP POST)
  • (二)【Jmeter】专栏实战项目靶场drupal部署
  • (附源码)ssm基于web技术的医务志愿者管理系统 毕业设计 100910
  • (三)Hyperledger Fabric 1.1安装部署-chaincode测试
  • (学习日记)2024.01.09
  • (转)Mysql的优化设置
  • (转)用.Net的File控件上传文件的解决方案
  • ../depcomp: line 571: exec: g++: not found
  • .[backups@airmail.cc].faust勒索病毒的最新威胁:如何恢复您的数据?
  • .net core使用RPC方式进行高效的HTTP服务访问
  • .net 验证控件和javaScript的冲突问题
  • 。Net下Windows服务程序开发疑惑
  • @LoadBalanced 和 @RefreshScope 同时使用,负载均衡失效分析
  • [ 渗透测试面试篇 ] 渗透测试面试题大集合(详解)(十)RCE (远程代码/命令执行漏洞)相关面试题
  • [20170728]oracle保留字.txt
  • [Assignment] C++1