重温设计模式--工厂模式(简单、工厂、抽象)

文章目录

  • 工厂模式定义
  • 工厂模式通常可以细分为以下几种类型
    • 1、简单工厂模式(Simple Factory Pattern)
    • 2、工厂方法模式(Factory Method Pattern)
    • 3、抽象工厂模式(Abstract Factory Pattern)
  • UML 图
    • 1、简单工厂模式UML
    • 2、工厂模式UML
    • 3、抽象工厂模式UML
  • C++ 代码示例。
    • 1、简单工厂模式
      • 结构及原理
        • 简单工厂模式包含以下几个关键部分:
    • 工厂方法模式
      • 结构及原理
        • 工厂方法模式在简单工厂模式基础上做了如下改变:
  • 抽象工厂模式
    • 结构及原理
    • C++ 代码示例
  • 总结

工厂模式定义

工厂模式(Factory Pattern)属于创建型设计模式,它主要用于对象的创建过程,将对象的创建和使用分离,把对象创建的逻辑封装在工厂类中,这样当需要创建对象时,不用在客户端代码里直接通过 new 操作符等去实例化对象,而是通过调用工厂类的相应方法来获取对象。这使得代码的维护性和可扩展性更好,也提高了代码的灵活性和可复用性。

工厂模式通常可以细分为以下几种类型

1、简单工厂模式(Simple Factory Pattern)

它是工厂模式的基础,虽然严格来说不算 GoF(Gang of Four,设计模式四人组)提出的 23 种设计模式之一,但却是理解工厂模式的重要起点。简单工厂模式有一个工厂类,该工厂类根据传入的参数等条件来决定创建哪种具体产品对象。

2、工厂方法模式(Factory Method Pattern)

在简单工厂模式上进行了改进,把具体产品对象的创建方法延迟到具体的工厂子类中实现,工厂类变成抽象类,有一个抽象的创建方法,每个具体的工厂子类负责创建对应的具体产品对象,符合开闭原则(对扩展开放,对修改关闭)。

3、抽象工厂模式(Abstract Factory Pattern)

更为复杂和抽象,工厂类负责创建一系列相关的产品对象,客户端调用抽象工厂类的抽象创建方法,由具体的工厂子类来创建符合特定需求的一组相关产品,常用于创建一组有内在关联、需要统一创建的对象场景。

UML 图

1、简单工厂模式UML

在这里插入图片描述

2、工厂模式UML

在这里插入图片描述

3、抽象工厂模式UML

在这里插入图片描述

C++ 代码示例。

1、简单工厂模式

结构及原理

简单工厂模式包含以下几个关键部分:

抽象产品(Product):定义产品对象的接口,描述了产品共有的行为和属性。
具体产品(ConcreteProduct):实现抽象产品接口,代表具体的产品对象,不同的具体产品有其独特的实现逻辑。
工厂类(Factory):负责创建具体的产品对象,根据传入的条件或者参数决定实例化哪种具体产品。
C++ 代码示例

#include <iostream>
#include <string>

// 抽象产品
class Product
{
public:
	virtual void use() = 0;
	virtual ~Product() {}
};

// 具体产品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:
	static Product* createProduct(const std::string& type)
	{
		if (type == "A")
		{
			return new ConcreteProductA();
		}
		else if (type == "B")
		{
			return new ConcreteProductB();
		}
		return nullptr;
	}
};

int main()
{
	Product* productA = Factory::createProduct("A");
	Product* productB = Factory::createProduct("B");

	if (productA)
	{
		productA->use();
		delete productA;
	}

	if (productB)
	{
		productB->use();
		delete productB;
	}
	char t;
	std::cin>>t;
	return 0;
}

在上述代码中:
Product 是抽象产品类,定义了 use 这个抽象方法,代表产品被使用时的操作。
ConcreteProductA 和 ConcreteProductB 是具体产品类,分别实现了 use 方法,有着各自不同的使用逻辑。
Factory 是工厂类,其 createProduct 静态方法根据传入的产品类型字符串来决定创建哪种具体产品对象,然后返回给客户端使用。在 main 函数中,通过工厂类创建了不同的产品对象并调用它们的 use 方法展示功能,最后记得释放内存,避免内存泄漏。

工厂方法模式

结构及原理

工厂方法模式在简单工厂模式基础上做了如下改变:

抽象工厂(Abstract Factory):作为工厂类的抽象,定义了抽象的创建产品的方法,具体的创建逻辑延迟到具体工厂子类中。
具体工厂(Concrete Factory):继承自抽象工厂,实现抽象的创建方法,负责创建对应的具体产品对象。
在简单工厂模式的基础上,把对象的创建分布在各个产品对应的工厂内,而不是在一个工厂内,更加符合开闭原则,简单工厂模式严格来说不符合开闭原则,因为他对修改还是开放的
C++ 代码示例

#include <iostream>
#include <string>

// 抽象产品
class Product 
{
public:
	virtual void use() = 0;
	virtual ~Product() {}
};

// 具体产品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 AbstractFactory
{
public:
	virtual Product* createProduct() = 0;
	virtual ~AbstractFactory() {}
};

// 具体工厂A,负责创建产品A
class ConcreteFactoryA : public AbstractFactory
{
public:
	Product* createProduct() override
	{
		return new ConcreteProductA();
	}
};

// 具体工厂B,负责创建产品B
class ConcreteFactoryB : public AbstractFactory
{
public:
	Product* createProduct() override
	{
		return new ConcreteProductB();
	}
};

int main()
{
	AbstractFactory* factoryA = new ConcreteFactoryA();
	AbstractFactory* factoryB = new ConcreteFactoryB();

	Product* productA = factoryA->createProduct();
	Product* productB = factoryB->createProduct();

	if (productA) 
	{
		productA->use();
		delete productA;
	}

	if (productB)
	{
		productB->use();
		delete productB;
	}

	delete factoryA;
	delete factoryB;

	return 0;
}

在这个代码中:
AbstractFactory 抽象工厂类定义了抽象的 createProduct 方法,让具体工厂子类去实现具体的创建逻辑。
ConcreteFactoryA 和 ConcreteFactoryB 分别是负责创建不同具体产品的具体工厂类,它们重写了 createProduct 方法来实例化对应的产品。在 main 函数中,先创建具体的工厂对象,再通过工厂对象创建相应的产品对象并使用,最后按顺序释放工厂对象和产品对象的内存,保证内存管理的正确性。

抽象工厂模式

结构及原理

抽象工厂模式的核心在于创建一系列相关的产品对象,其结构特点如下:
抽象工厂(Abstract Factory):定义了创建一系列相关产品的抽象方法,例如创建产品 A、产品 B 等多个抽象方法(在更复杂场景中可能更多)。
具体工厂(Concrete Factory):实现抽象工厂接口,负责创建一组特定的相关产品对象,满足特定的业务需求组合。
抽象产品族(Abstract Product Family):包含多个抽象产品类,这些抽象产品类通常在业务上是相关联的,一起构成了产品族的抽象定义。
具体产品(Concrete Product):实现抽象产品族中的相应抽象产品类,代表具体的产品对象,不同的具体工厂创建不同组合的具体产品。

C++ 代码示例

下面以一个简单的游戏开发中创建不同主题风格的游戏角色和武器为例(比如有魔幻主题和科幻主题):

#include <iostream>
#include <string>

// 抽象产品:游戏角色
class Character
{
public:
	virtual void show() = 0;
	virtual ~Character() {}
};

// 抽象产品:游戏武器
class Weapon
{
public:
	virtual void attack() = 0;
	virtual ~Weapon() {}
};

// 具体产品:魔幻角色
class MagicCharacter : public Character 
{
public:
	void show() override
	{
		std::cout << "A magic character appears." << std::endl;
	}
};

// 具体产品:魔幻武器
class MagicWeapon : public Weapon
{
public:
	void attack() override 
	{
		std::cout << "Magic weapon attacks with spells." << std::endl;
	}
};

// 具体产品:科幻角色
class SciFiCharacter : public Character 
{
public:
	void show() override
	{
		std::cout << "A sci-fi character appears." << std::endl;
	}
};

// 具体产品:科幻武器
class SciFiWeapon : public Weapon
{
public:
	void attack() override 
	{
		std::cout << "Sci-fi weapon attacks with energy beams." << std::endl;
	}
};

// 抽象工厂
class AbstractFactory
{
public:
	virtual Character* createCharacter() = 0;
	virtual Weapon* createWeapon() = 0;
	virtual ~AbstractFactory() {}
};

// 具体工厂:魔幻主题工厂
class MagicFactory : public AbstractFactory
{
public:
	Character* createCharacter() override
	{
		return new MagicCharacter();
	}
	Weapon* createWeapon() override
	{
		return new MagicWeapon();
	}
};

// 具体工厂:科幻主题工厂
class SciFiFactory : public AbstractFactory 
{
public:
	Character* createCharacter() override
	{
		return new SciFiCharacter();
	}
	Weapon* createWeapon() override 
	{
		return new SciFiWeapon();
	}
};


int main()
{
	AbstractFactory* magicFactory = new MagicFactory();
	AbstractFactory* sciFiFactory = new SciFiFactory();

	// 创建魔幻主题的角色和武器
	Character* magicCharacter = magicFactory->createCharacter();
	Weapon* magicWeapon = magicFactory->createWeapon();

	// 创建科幻主题的角色和武器
	Character* sciFiCharacter = sciFiFactory->createCharacter();
	Weapon* sciFiWeapon = sciFiFactory->createWeapon();

	if (magicCharacter) 
	{
		magicCharacter->show();
		delete magicCharacter;
	}

	if (magicWeapon)
	{
		magicWeapon->attack();
		delete magicWeapon;
	}

	if (sciFiCharacter)
	{
		sciFiCharacter->show();
		delete sciFiCharacter;
	}

	if (sciFiWeapon)
	{
		sciFiWeapon->attack();
		delete sciFiWeapon;
	}

	delete magicFactory;
	delete sciFiFactory;

	char t;
	std::cin>>t;

	return 0;
}

在这个示例中:
Character 和 Weapon 分别是抽象的游戏角色和武器产品类,定义了各自展示和攻击的抽象方法。
MagicCharacter、MagicWeapon、SciFiCharacter、SciFiWeapon 是对应的具体产品类,实现了各自的具体行为逻辑。
AbstractFactory 是抽象工厂类,定义了创建角色和武器的抽象方法。
MagicFactory 和 SciFiFactory 是具体工厂类,分别负责创建魔幻主题和科幻主题的角色和武器这一组相关产品。在 main 函数中,通过不同的具体工厂创建相应主题的产品并调用其方法展示功能,最后正确释放所有创建对象所占用的内存。

总结

简单工厂模式、工厂模式、抽象工厂模式是逐渐递进,
1、简单工厂模式是在一个工厂内生产多个产品;
2、工厂模式是一个工厂生产一个产品;
3、抽象工厂模式是一个工厂生产多个产品。

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

华为手机鸿蒙4.2连接不上adb

1、下载HiSuite华为手机助手 https://consumer.huawei.com/cn/support/hisuite/ 2、安装后点连接 3、就可以adb连接了

重温设计模式--代理模式

文章目录 定义UML图代理模式主要有以下几种常见类型&#xff1a;代理模式涉及的主要角色有&#xff1a;C 代码示例 定义 代理模式&#xff08;Proxy Pattern&#xff09;属于结构型设计模式&#xff0c;它为其他对象提供一种代理以控制对这个对象的访问。 通过引入代理对象&am…

JAVA开发入门学习七- 数组

数组的概念 概念 数组&#xff1a; 是多个相同类型数据按照一定排列的集合&#xff0c;并使用一个名字命名&#xff0c;并通过编号的方式对这些数据进行统一管理 数组中的概念 数组名&#xff1a; 数组的名称&#xff0c;命名 下标&#xff1a; 从0开始 元素&#xff1a;…

ECharts热力图-笛卡尔坐标系上的热力图,附视频讲解与代码下载

引言&#xff1a; 热力图&#xff08;Heatmap&#xff09;是一种数据可视化技术&#xff0c;它通过颜色的深浅变化来表示数据在不同区域的分布密集程度。在二维平面上&#xff0c;热力图将数据值映射为颜色&#xff0c;通常颜色越深表示数据值越大&#xff0c;颜色越浅表示数…

【解决问题】Java2DRenderer生成图片时中文乱码 Linux安装字体

一&#xff0c;问题 在使用Java2DRenderer框架将html生成图片时&#xff0c;html中的中文文本在图片上显示框框&#xff0c;即出现了中文乱码。在确认使用正确的字符编码utf-8之后&#xff0c;并且确认了修改成unicode也同样乱码的情况下&#xff0c;找到了真正的原因&#xf…

HTMLCSSJavaScriptDOM 之间的关系?

一、HTML 中文名&#xff1a;超文本标记语言 英文名&#xff1a;HyperText Markup Language HTML是一种用来结构化Web网页及其内容的标记语言。 HTML 由一系列的元素组成&#xff0c;这些元素可以用来包围不同部分的内容&#xff0c;使其以某种方式呈现或者工作。 图Ⅰ 每…

Linux系统编程深度解析:C语言实战指南

文章一览 前言一、gcc编译系统1.1 文件名后缀1.2 C语言编译过程1.3 gcc命令行选项 二、gdb程序调试工具2.1 启动gdb和查看内部命令2.2 显示源程序和数据2.2.1 显示和搜索源程序2.2.2 查看运行时数据 2.3 改变和显示目录或路径2.4 控制程序的执行2.4.1 设置断点2.4.2 显示断点2.…

使用QML实现播放器进度条效果

使用QML实现播放进度效果 QML Slider介绍 直接上DEMO如下&#xff1a; Slider {width: 300;height: 20;orientation: Qt.Vertical; //决定slider是横还是竖 默认是HorizontalstepSize: 0.1;value: 0.2;tickmarksEnabled: true; //显示刻度}效果图如下 那么我先改变滑块跟滚轮…

云数智融合体系建设实践——以工行软件开发中心为例

随着“云计算第三次浪潮”的涌动&#xff0c;业界正见证着一场围绕“算力”的结构性变革。云计算、大数据、人工智能三大核心技术的深度融合&#xff0c;正推动着算力基础设施的快速发展&#xff0c;实现算力的高效调度与利用&#xff0c;也标志着业界对云计算体系布局的全新理…

评估大语言模型在药物基因组学问答任务中的表现:PGxQA

​这篇文献主要介绍了一个名为PGxQA的资源&#xff0c;用于评估大语言模型&#xff08;LLM&#xff09;在药物基因组学问答任务中的表现。 研究背景 药物基因组学&#xff08;Pharmacogenomics, PGx&#xff09;是精准医学中最有前景的领域之一&#xff0c;通过基因指导的治疗…

com.google.common.collect.ImmutableList$SerializedForm

今天AndroidStudio安装了个2021版本的&#xff0c;gradle用了7.3.3&#xff0c;创建项目后控制台总是有这样一个错误&#xff1a; Unable to load class com.google.common.collect.ImmutableList$SerializedForm. This is an unexpected error. Please file a bug containing…

[机器学习]sklearn入门指南(2)

上一篇文章中&#xff0c;我们介绍了如何用sklearn训练和预测模型&#xff0c;以及缺失值处理&#xff0c;详见[机器学习]sklearn入门指南&#xff08;1&#xff09; 分类变量 分类变量&#xff08;Categorical Variable&#xff09;&#xff0c;也称为定性变量&#xff08;Q…

CentOS下,离线安装vscode的步骤;

前置条件&#xff1a; 1.CentOS7; 步骤&#xff1a; 1.下载vscode指定版本&#xff0c;例如&#xff1b; 例如 code-1.83.1-1696982959.el7.x86_64.rpm 2.使用下面命令&#xff1a; sudo rpm -ivh code-1.83.1-1696982959.el7.x86_64.rpm 其他&#xff1a; 卸载vscode的命…

AI一键制作圣诞帽头像丨附详细教程

我用AI换上圣诞帽头像啦~&#x1f385; 不管是搞笑表情、宠物头像还是你的自拍&#xff01;&#xff01;都能一键添加圣诞帽元素&#xff0c;毫无违和感&#xff01;&#x1f389; 详细教程在P3、P4&#xff0c;手残党也能轻松搞定&#xff01; 宝子们需要打“need”&#xff0…

基于java博网即时通讯软件的设计与实现【源码+文档+部署讲解】

目 录 1. 绪 论 1.1. 开发背景 1.2. 开发意义 2. 系统设计相关技术 2.1 Java语言 2.2 MySQL数据库 2.3 Socket 3. 系统需求分析 3.1 可行性分析 3.2 需求分析 3.3 系统流程图 3.4 非功能性需求 4. 系统设计 4.1 系统功能结构 4.2 数据库设计 5. 系统实现 5.…

智能公文写作一体机,开箱即用快速部署超便捷

在繁忙的政企事业单位中&#xff0c;时间就是生产力。公文撰写作为各类组织日常工作的核心环节&#xff0c;却常常因为传统的公文处理流程繁琐耗时而成为效率的瓶颈。如何打破这一瓶颈&#xff0c;实现高效的公文撰写&#xff0c;成为了众多单位关注的焦点。 一款即开即用的公文…

idea2024创建JavaWeb项目以及配置Tomcat详解

今天呢&#xff0c;博主的学习进度也是步入了JavaWeb&#xff0c;目前正在逐步杨帆旗航&#xff0c;迎接全新的狂潮海浪。 那么接下来就给大家出一期有关JavaWeb的配置教学&#xff0c;希望能对大家有所帮助&#xff0c;也特别欢迎大家指点不足之处&#xff0c;小生很乐意接受正…

从零开始使用MaxKB打造本地大语言模型智能问答系统与远程交互

文章目录 前言1. 下载运行Ollama2. 安装大语言模型3. 安装Cpolar工具4. 配置公网地址5. 固定公网地址6. MaxKB 添加Olama7.创建问答应用 前言 目前大语言模型&#xff08;LLM&#xff09;已经成为了人工智能领域的一颗璀璨明星&#xff0c;从自然语言处理到智能问答系统&#…

二年级数学知识边界总结思考-下册

目录 一、背景二、过程1.数据收集和整理一、知识点二、由来三、作用和意义 2.图形的运动一、知识点二、由来三、作用和意义 3.小小设计师一、知识点二、由来三、作用和意义 4.克和千克一、知识点二、由来三、作用和意义 5.数学广角-推理一、知识点二、由来三、作用和意义 三、总…

企业数字化转型加速,现代 IT 如何用 Datadog 全面提升可观测性?

作为 Gartner 可观测平台魔力象限的领导者&#xff0c;Datadog 凭借全面的功能、直观的用户界面和强大的产品路线图赢得了全球企业的信任。 企业 IT 架构正变得日益复杂&#xff0c;从本地服务器到云端部署&#xff0c;从单体应用向微服务&#xff0c;还有容器、 Kubernetes 等…