C++设计模式——工厂模式 :简单工厂、工厂方法、抽象工厂

工厂模式可以分为三种,简单工厂模式,工厂方法模式和抽象工厂模式。
那么,这三种工厂模式长啥样,又为啥会衍生出这三种模式来呢?本篇和大家一起来学习总结一下。

一、简单工厂模式

简单工厂SimpleFactory 负责创建所有实例的内部逻辑。
工厂类的创建产品类的方法可以被外界直接调用,创建所需的产品对象。

简单工厂模式

//SimpleFactory.h
#pragma once#include <iostream>
#include <string>
#include <functional>using namespace std;
#define MYTRACE()  { cout << __FUNCTION__  << std::endl; }/**
* 产品的抽象类(抽象产品类)
*/
class AbstractProduct
{
public:virtual ~AbstractProduct() { MYTRACE ()}virtual void show() = 0;
};/**
* 中国产品 (具体产品类)
*/
class ChineseProduct : public AbstractProduct
{
public:ChineseProduct() {}~ChineseProduct() {MYTRACE()}void show() override{MYTRACE()}
};/**
* 日本产品 (具体产品类)
*/
class JapaneseProduct : public AbstractProduct
{
public:JapaneseProduct() {}~JapaneseProduct() {MYTRACE()}void show() override{MYTRACE()}
};/*
* 具体工厂类:负责每一个具体产品的创建业务逻辑
*/class SimpleFactory
{
public:enum  class ProductType {ChineseProductType,JapaneseProductType};static AbstractProduct* CreateProduct(ProductType type){switch (type){case SimpleFactory::ProductType::ChineseProductType:return new ChineseProduct;case SimpleFactory::ProductType::JapaneseProductType:return new JapaneseProduct;}}
};
// main.cpp
#include <iostream>
#include "simpleFactory.h"
#include <vector>int main()
{std::vector<AbstractProduct*> v;v.resize(2);v[0] = SimpleFactory::CreateProduct(SimpleFactory::ProductType::ChineseProductType);v[1] = SimpleFactory::CreateProduct(SimpleFactory::ProductType::JapaneseProductType);for (int i = 0; i < v.size(); ++i) {if (v[i] != nullptr) {v[i]->show();delete v[i];v[i] = nullptr;}}return 0;
}

简单工厂优缺点

优点:
(1)帮助封装:实现组件封装,面向接口编程
(2) 延迟了子类的实例化
(3)解耦合:客户端和具体实现类的解耦合

缺点:
(1)可能增加客户端的复杂度
(2)不方便扩展子工厂

二、工厂方法模式

在这里插入图片描述

//PolymorphicFactory.h
#pragma once#include <iostream>
#include <string>
#include <functional>using namespace std;
#define MYTRACE()  { cout << __FUNCTION__  << std::endl; }/**
* 产品的抽象类(抽象产品类)
*/
class AbstractProduct
{
public:virtual ~AbstractProduct() {MYTRACE()}virtual void makeProduct() = 0;
};class AbstractFactory 
{
public:virtual ~AbstractFactory() { MYTRACE() }virtual AbstractProduct* createProduct() = 0;
};/**
* 中国产品 (具体产品类)
*/
class ChineseProduct : public AbstractProduct
{
public:ChineseProduct() {}~ChineseProduct() { MYTRACE() }void makeProduct() override { MYTRACE() }
};class ChineseFactory : public AbstractFactory
{
public:virtual AbstractProduct* createProduct() override {MYTRACE()return new ChineseProduct;}
};/**
* 日本产品 (具体产品类)
*/
class JapaneseProduct : public AbstractProduct
{
public:JapaneseProduct() {}~JapaneseProduct() { MYTRACE()}void makeProduct() override{ MYTRACE()}
};class JapaneseFactory : public AbstractFactory
{
public:virtual AbstractProduct* createProduct() override {MYTRACE()return new JapaneseProduct;}
};
#include <iostream>
#include "PolymorphicFactory.h"
#include <cstdio>int main()
{// 中国工厂AbstractFactory* c_factory = new ChineseFactory;// 开产线AbstractProduct* c_product =  c_factory->createProduct();// 制造该产品c_product->makeProduct();// 日本工厂AbstractFactory* j_factory = new JapaneseFactory;// 开产线AbstractProduct* j_product = j_factory->createProduct();// 制造该产品j_product->makeProduct();return 0;
}

工厂方法优缺点

优点:
(1)帮助封装:实现组件封装,面向接口编程
(2) 延迟了子类的实例化
(3)解耦合:客户端和具体实现类的解耦合
(4)需求改变时改动最小

缺点:
(1)新增功能时,工作量稍大

三、抽象工厂模式

AbstractFactory 模式就是用来解决这类问题:要创建一组相关或者相互依赖的对象。AbstractFactory模式关键 就是将这一组对象的创建封装到一个用于创建对象的类(ConcreteFactory)中,维护这样一个创建类总比维护n多相关对象的创建过程要简单的多。
抽象工厂模式

//Product.h
#ifndef _PRODUCT_H_
#define _PRODUCT_H_#include <iostream>
#include <string>using namespace std;
#define MYTRACE  { cout << __FUNCTION__  << std::endl; }class AbstractProductA
{
public:virtual ~AbstractProductA(){MYTRACE}
protected:AbstractProductA(){MYTRACE}
private:
};class AbstractProductB
{
public:virtual ~AbstractProductB(){MYTRACE}
protected:AbstractProductB(){MYTRACE}
private:
};class ProductA1: public AbstractProductA
{
public:ProductA1(){MYTRACE}~ProductA1(){MYTRACE}
protected:
private:
};class ProductA2:public AbstractProductA
{
public:ProductA2(){MYTRACE}~ProductA2(){MYTRACE}
protected:
private:
};class ProductB1: public AbstractProductB
{
public:ProductB1(){MYTRACE}~ProductB1(){MYTRACE}
protected:
private:
};class ProductB2: public AbstractProductB
{
public:ProductB2(){MYTRACE}~ProductB2(){MYTRACE}
protected:
private:
};#endif //_PRODUCT_H_
// factory.h
#ifndef FACTORY_H
#define FACTORY_H#include "product.h"class AbstractFactory
{
public:virtual ~AbstractFactory(){}virtual AbstractProductA* createProductA() = 0;virtual AbstractProductB* createProductB() = 0;
protected:AbstractFactory(){}
};/*!* \brief The ConcreteFactory1 class   生产一类产品:A1和B1*/
class ConcreteFactory1: public AbstractFactory
{
public:ConcreteFactory1(){}~ConcreteFactory1(){}AbstractProductA* createProductA() override{ return new ProductA1;}AbstractProductB* createProductB() override{ return new ProductB1;}
protected:
private:
};/*!* \brief The ConcreteFactory2 class    生产二类产品:A2和B2*/
class ConcreteFactory2:public AbstractFactory
{
public:ConcreteFactory2(){}~ConcreteFactory2(){}AbstractProductA* createProductA() override{ return new ProductA2;}AbstractProductB* createProductB() override{ return new ProductB2;}
protected:
private:
};#endif // FACTORY_H
#include <iostream>
#include "factory.h"int main(/*int argc, char *argv[]*/)
{AbstractFactory* cf1  = new ConcreteFactory1;cf1->createProductA();cf1->createProductB();AbstractFactory* cf2  = new ConcreteFactory2;cf2->createProductA();cf2->createProductB();return 0;
}

抽象工厂模式
抽象工厂模式优缺点
优点:

  1. 抽象工厂封装了变化,封装了对象创建的具体细节
  2. 增加新的产品族很方便,无须修改已有系统
  3. 针对接口进行编程而不是针对具体产品对象进行编程

缺点:

  1. 增加新的产品等级结构需对原系统做较大修改(违背开放封闭)

四、总结

在前面三个部分,我们说了三种不同工厂模式的实现,以及各自的优缺点。那么,是不是说抽象工厂模式就是最好的呢,显然不是,具体的使用哪种模式,还要结合业务场景需求~

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/180128.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

Webpack——模块打包

模块之于程序&#xff0c;就如同细胞之于生物体&#xff0c;是具有特定功能的组成单元。不同的模块负责不同的工作&#xff0c;它们以某种方式联系在一起&#xff0c;共同保证程序的正常运转。介绍Webpack如何对其进行打包以及合并&#xff0c;主要内容如下&#xff1a; 不同模…

使用OSS搭建私有云内网yum仓库的方法

使用OSS搭建私有云内网yum仓库的方法 文字&图片内容已脱敏 #、前几天接到一个搭建内网yum源的任务。刚接到这个任务的时候还是比较头疼的&#xff0c;因为内部有很多VPC。VPC与VPC之间是不互通的&#xff0c;又不能打高速通道&#xff0c;也不可能每个VPC下边都建一个yum…

Python 判断域名是否合规且是否可访问

需求 获得参数为域名的字符串后 1. 判定是否为合规域名 2. 该域名是否活着&#xff08;可访问&#xff09; 实例 headers { # 默认标头User-Agent: $,Accept: text/html,application/xhtmlxml,application/xml;q0.9,*/*;q0.8,Accept-Language: en-US,en;q0.5,Accept-Enc…

csv文件EXCEL默认打开乱码问题

这里讨论的问题是&#xff0c;当用记事本打开带有中文字符的csv正常时&#xff0c;用excel打开却是乱码。 简单概括就是&#xff1a;编码问题&#xff0c;windows的 excel打开csv文本文件时&#xff0c;默认使用的是系统内的ANSI&#xff0c;在中文环境下就是GB2312。如果写文件…

mySQL踩坑记录

1.MYSQL Workbench-8.0.27.1出现"Exception: Current profile has no WMI enabled"错误的解决方法 MYSQL Workbench-8.0.27.1出现“Exception: Current profile has no WMI enabled“错误的解决方法_赛风扥的博客-CSDN博客 C:\Program Files\MySQL\MySQL Workbench …

windows11 phpstudy_pro php8.2 安装redis扩展

环境&#xff1a;windows11 phpstudy_pro php8.2.9 一、命令查看是否安装redis扩展 在对应网站中通过打开&#xff0c;&#xff0c;选择对应的PHP版本&#xff0c;用命令 php -m 查看自己的php 有没有redis扩展 上面如果有&#xff0c;说明已经安装了,如果没有安装&#xff1…

AWL中英文对照表

Sublist 1 sector&#xff1a;部门、 available&#xff1a;可用的、 financial&#xff1a;财务的、 process&#xff1a;过程、 individual&#xff1a;个人的、 specific&#xff1a;具体的、 principle&#xff1a;原则、 estimate&#xff1a;估计、 variables&#xff1…

5 时间序列预测入门:LSTM+Transformer

0 引言 论文地址&#xff1a;https://arxiv.org/abs/1706.03762 1 Transformer Transformer 模型是一种用于处理序列数据的深度学习模型&#xff0c;主要用于解决自然语言处理&#xff08;NLP&#xff09;任务。它在许多 NLP 任务中取得了重大突破&#xff0c;如机器翻译、文本…

docker安装elasticsearch

1、拉取镜像 docker pull elasticsearch:7.17.5 (听说这玩意不同版本有不同的坑&#xff0c;不兼容程序等等&#xff0c;所以要注意下载对应版本号) 2、创建挂载目录 mkdir -p /mydata/elasticsearch/config mkdir -p /mydata/elasticsearch/data echo "http.host: …

Linux内存管理(六十四):ION 内存管理器——system heap

源码基于:Linux 5.4 约定: 芯片架构:ARM64内存架构:UMACONFIG_ARM64_VA_BITS:39CONFIG_ARM64_PAGE_SHIFT:12CONFIG_PGTABLE_LEVELS :30. 前言 ION 是 Google 在 Android 4.0 中引入,目的主要是通过在硬件设备和用户空间之间分配和共享内存,实现设备之间零拷贝共享内存…

Servlet-Vue-JSON交互

Servlet-Vue-JSON交互 统一结果返回 定义 package org.example.result;import lombok.AllArgsConstructor; import lombok.Data; import lombok.NoArgsConstructor;Data NoArgsConstructor AllArgsConstructor public class Result<T> {private Integer code;private St…

Android Studio 模拟器设置独立窗口

目录 模拟器在窗口内部运行 设置成独立窗口 模拟器在窗口内部运行 操作起来十分不便 设置成独立窗口 Android Studio -> Preferences(Settings) -> Tools-> Emulator ->取消勾选 Launch in a tool window -> 点击右下角的 OK 按钮 -> 重启 Android Studio

Python与微信交互(互动)神器yyds

Weixin-Python 是一个用于开发微信公众平台应用的 Python 库。它可以帮助你轻松地处理微信服务器发来的消息&#xff0c;以及向用户发送各种类型的消息。 Weixin-Python 的主要功能包括&#xff1a; 验证微信服务器的签名&#xff0c;确保请求来自微信服务器。解析微信服务器发…

前端---CSS篇(详解CSS)

1.CSS简介 CSS(Cascading Style Sheets)层叠样式表&#xff0c;是用来为结构化文档&#xff08;HTML、XML等应用&#xff09;添加样式,比如字体、颜色、大小、间距的计算机语言。CSS目前已经发展到了CSS3.0了。 2.CSS导入方式 CSS有三种导入方式&#xff1a; 1.行内样式&am…

MySQL在Docker容器中的性能损失分析与优化策略

文章目录 1. Docker容器对MySQL性能的潜在影响1.1. IO性能1.2. 网络性能1.3. 资源隔离 2. 优化策略2.1. 使用本地数据卷2.2. 配置合理的容器网络2.3. 限制容器资源2.4. 使用容器编排工具 3. 性能测试与监控4. 结论 &#x1f389;MySQL在Docker容器中的性能损失分析与优化策略 ☆…

Positive Technologies 公司发布了一种保护容器环境的产品 PT Container Security

根据 Positive Technologies 公司的数据&#xff0c;该类产品在俄罗斯的市场容量为 25 亿卢布&#xff0c;据预测&#xff0c;到 2026 年将增长两倍 Positive Technologies 公司正在增加应用安全方面的产品组合。新产品 PT Container Security可在构建、部署和工业运行阶段自动…

[MySQL--基础]函数、约束

hello! 这里是欧_aita的频道。 今日语录:不管你觉得自己能做什么&#xff0c;或者你觉得你不能做什么&#xff0c;你都是对的。 祝福语&#xff1a;愿你的程序像太阳一样明亮&#xff0c;给世界带来温暖和光明。 大家可以在评论区畅所欲言&#xff0c;可以指出我的错误&#xf…

转载:利用Flask实现深度学习模型部署

推荐博客 深度学习模型部署篇——利用Flask实现深度学习模型部署&#xff08;三&#xff09; pytorch中文文档-通过带Flask的REST API在Python中部署PyTorch 利用flask搭建深度学习服务

吴恩达《机器学习》10-6-10-7:学习曲线、决定下一步做什么

一、学习曲线 1. 学习曲线概述 学习曲线将训练集误差和交叉验证集误差作为训练集实例数量&#xff08;m&#xff09;的函数绘制而成。这意味着从较少的数据开始&#xff0c;逐渐增加训练集的实例数量。该方法的核心思想在于&#xff0c;当训练较少数据时&#xff0c;模型可能…

JDK 21 新特性一览

Java 21 已于 2023 年 9 月 19 日发布&#xff0c;是 Oracle 标准 Java 实现的下一个长期支持&#xff08;LTS&#xff09;版本。Java 21 具有以下 15 项新特性。 String Templates (Preview) 字符串模板&#xff0c;可以像其他语言那样子方便的做字符串拼接&#xff0c;是号&…