工厂方法模式与抽象工厂模式
工厂方法模式 (Factory Method)
定义: 工厂方法模式是一种创建型设计模式,它定义了一个用于创建对象的接口,但让子类决定实例化哪个类。工厂方法将类的实例化推迟到子类。
优点:
- 解耦:客户端代码与具体的产品类解耦,只依赖于产品的接口。
- 可扩展性:新增产品只需实现相应的工厂方法,无需修改现有代码。
- 灵活性:可以根据具体需求选择不同的产品。
应用场景:
- 当一个类不知道它所需要的对象的类时。
- 当一个类希望通过子类来指定所创建的对象时。
- 当类的实例化过程非常复杂时。
C++ 示例代码
以下是一个简单的工厂方法模式示例,展示了如何创建不同类型的汽车。
1. 产品接口
首先,我们定义一个汽车的接口。
#include <iostream>
#include <memory>// 产品接口
class Car {
public:virtual void drive() = 0; // 驾驶方法virtual ~Car() = default; // 虚析构函数
};
2. 具体产品
接下来,我们定义具体的汽车类,分别实现 Car 接口。
// 具体产品:轿车
class Sedan : public Car {
public:void drive() override {std::cout << "Driving a Sedan.\n";}
};// 具体产品:SUV
class SUV : public Car {
public:void drive() override {std::cout << "Driving an SUV.\n";}
};
3. 工厂接口
然后,我们定义一个工厂接口,用于创建汽车对象。
// 工厂接口
class CarFactory {
public:virtual std::unique_ptr<Car> createCar() = 0; // 工厂方法virtual ~CarFactory() = default; // 虚析构函数
};
4. 具体工厂
实现具体工厂类,分别创建不同类型的汽车。
// 具体工厂:轿车工厂
class SedanFactory : public CarFactory {
public:std::unique_ptr<Car> createCar() override {return std::make_unique<Sedan>(); // 创建轿车}
};// 具体工厂:SUV工厂
class SUVFactory : public CarFactory {
public:std::unique_ptr<Car> createCar() override {return std::make_unique<SUV>(); // 创建SUV}
};
5. 客户端代码
最后,我们在客户端代码中使用这些工厂。
int main() {// 创建轿车工厂并生产轿车std::unique_ptr<CarFactory> sedanFactory = std::make_unique<SedanFactory>();std::unique_ptr<Car> sedan = sedanFactory->createCar();sedan->drive(); // 输出: Driving a Sedan.// 创建SUV工厂并生产SUVstd::unique_ptr<CarFactory> suvFactory = std::make_unique<SUVFactory>();std::unique_ptr<Car> suv = suvFactory->createCar();suv->drive(); // 输出: Driving an SUV.return 0;
}
总结
在这个示例中,工厂方法模式允许我们通过不同的工厂类创建不同类型的汽车。客户端代码只需要依赖于 CarFactory 和 Car 接口,而不需要了解具体的汽车实现。这种解耦设计提高了代码的灵活性和可维护性,便于未来的扩展。
- 抽象工厂模式
抽象工厂模式 (Abstract Factory)
定义: 抽象工厂模式是一种创建型设计模式,它提供一个接口,用于创建一系列相关或相互依赖的对象,而无需指定它们的具体类。通过这种方式,抽象工厂模式可以使客户端代码与具体产品的实现解耦。
优点:
- 解耦:客户端不需要依赖具体产品类,可以通过抽象接口进行交互。
- 可扩展性:如果需要增加新的产品,只需实现新的工厂和产品类,无需修改现有代码。
- 一致性:确保产品之间的兼容性和一致性。
应用场景:
- 当系统需要独立于其产品的创建、组合和表示时。
- 当系统需要根据不同的配置来生成一系列相关的产品时。
C++ 示例代码
以下是一个简单的抽象工厂模式示例,展示了如何创建不同类型的家具(椅子和沙发)。
1. 产品接口
首先,我们定义椅子和沙发的接口。
#include <iostream>
#include <memory>// 椅子接口
class Chair {
public:virtual void sitOn() = 0; // 坐下的方法virtual ~Chair() = default; // 虚析构函数
};// 沙发接口
class Sofa {
public:virtual void lieOn() = 0; // 躺下的方法virtual ~Sofa() = default; // 虚析构函数
};
2. 具体产品
接下来,我们定义具体的椅子和沙发类。
// 具体产品:现代椅子
class ModernChair : public Chair {
public:void sitOn() override {std::cout << "Sitting on a Modern Chair.\n";}
};// 具体产品:古典椅子
class VictorianChair : public Chair {
public:void sitOn() override {std::cout << "Sitting on a Victorian Chair.\n";}
};// 具体产品:现代沙发
class ModernSofa : public Sofa {
public:void lieOn() override {std::cout << "Lying on a Modern Sofa.\n";}
};// 具体产品:古典沙发
class VictorianSofa : public Sofa {
public:void lieOn() override {std::cout << "Lying on a Victorian Sofa.\n";}
};
3. 抽象工厂
然后,我们定义一个抽象工厂接口,用于创建椅子和沙发。
// 抽象工厂接口
class FurnitureFactory {
public:virtual std::unique_ptr<Chair> createChair() = 0; // 创建椅子的方法virtual std::unique_ptr<Sofa> createSofa() = 0; // 创建沙发的方法virtual ~FurnitureFactory() = default; // 虚析构函数
};
4. 具体工厂
实现具体工厂类,分别创建现代和古典家具。
// 具体工厂:现代家具工厂
class ModernFurnitureFactory : public FurnitureFactory {
public:std::unique_ptr<Chair> createChair() override {return std::make_unique<ModernChair>(); // 创建现代椅子}std::unique_ptr<Sofa> createSofa() override {return std::make_unique<ModernSofa>(); // 创建现代沙发}
};// 具体工厂:古典家具工厂
class VictorianFurnitureFactory : public FurnitureFactory {
public:std::unique_ptr<Chair> createChair() override {return std::make_unique<VictorianChair>(); // 创建古典椅子}std::unique_ptr<Sofa> createSofa() override {return std::make_unique<VictorianSofa>(); // 创建古典沙发}
};
5. 客户端代码
最后,我们在客户端代码中使用这些工厂。
int main() {// 创建现代家具工厂std::unique_ptr<FurnitureFactory> modernFactory = std::make_unique<ModernFurnitureFactory>();std::unique_ptr<Chair> modernChair = modernFactory->createChair();std::unique_ptr<Sofa> modernSofa = modernFactory->createSofa();modernChair->sitOn(); // 输出: Sitting on a Modern Chair.modernSofa->lieOn(); // 输出: Lying on a Modern Sofa.// 创建古典家具工厂std::unique_ptr<FurnitureFactory> victorianFactory = std::make_unique<VictorianFurnitureFactory>();std::unique_ptr<Chair> victorianChair = victorianFactory->createChair();std::unique_ptr<Sofa> victorianSofa = victorianFactory->createSofa();victorianChair->sitOn(); // 输出: Sitting on a Victorian Chair.victorianSofa->lieOn(); // 输出: Lying on a Victorian Sofa.return 0;
}
总结
在这个示例中,抽象工厂模式允许我们通过不同的工厂类创建不同类型的家具(椅子和沙发)。客户端代码只依赖于 FurnitureFactory 和产品接口,而不需要了解具体的家具实现。这种解耦设计提高了代码的灵活性和可维护性,便于未来的扩展和修改。通过这种模式,可以确保创建的家具产品之间的一致性和相互适配。
相关文章:
工厂方法模式与抽象工厂模式
工厂方法模式 (Factory Method) 定义: 工厂方法模式是一种创建型设计模式,它定义了一个用于创建对象的接口,但让子类决定实例化哪个类。工厂方法将类的实例化推迟到子类。 优点: 解耦:客户端代码与具体的产品类解耦…...
「Math」初等数学知识点大纲(占位待处理)
✨博客主页何曾参静谧的博客📌文章专栏「C/C」C/C程序设计📚全部专栏「VS」Visual Studio「C/C」C/C程序设计「UG/NX」BlockUI集合「Win」Windows程序设计「DSA」数据结构与算法「UG/NX」NX二次开发「QT」QT5程序设计「File」数据文件格式「PK」Parasoli…...
百元高性价比头戴式降噪耳机选哪款?四款平价性价比品牌别错过!
随着科技的发展,现在的头戴式耳机真的是越来越多样了,很多的朋友在选购耳机的时候,不知道哪一款头戴式耳机的性价比较高,究竟百元高性价比头戴式降噪耳机选哪款?身为一名数码爱好者,这里就给大家推带来四款…...
vue3 setup写不写到标签上的区别
在vue3种setup的写法,可以单独写setup()也可以写到script标签中,当然我们推荐后面这种 他的好处有很多,代码也简洁很多。1、属性和方法无需return,可直接使用 /*原先*/ <script> import { defineComponent } from "v…...
【论文解读】EdgeYOLO:一种边缘实时目标检测器(附论文地址)
论文地址:https://arxiv.org/pdf/2302.07483 这篇文章的标题是《EdgeYOLO: An Edge-Real-Time Object Detector》,由中国北京理工大学的Shihan Liu、Junlin Zha、Jian Sun、Zhuo Li和Gang Wang共同撰写。这篇论文提出了一个基于最新YOLO框架的高效、低复…...
xlwings,让excel飞起来!
excel已经成为必不可少的数据处理软件,几乎天天在用。python有很多支持操作excel的第三方库,xlwings是其中一个。 关于xlwings xlwings开源免费,能够非常方便的读写Excel文件中的数据,并且能够进行单元格格式的修改。 xlwings还…...
C语言学习,标准库 <stddef.h>
<stddef.h> C 标准库中头文件,它定义了一些常用的类型定义和宏。这些定义通常用于指针操作、数组处理和其他需要固定大小数据类型的场合。 size_t: 这是一个无符号整数类型,用于表示对象的大小(以字节为单位)。…...
PyQt5实战——操作台打印重定向,主界面以及stacklayout使用(四)
个人博客:苏三有春的博客 系类往期文章: PyQt5实战——多脚本集合包,前言与环境配置(一) PyQt5实战——多脚本集合包,UI以及工程布局(二) PyQt5实战——多脚本集合包,程序…...
React + Vite + TypeScript + React router项目搭建教程
一、创建项目 运行项目 二、目录结构 项目目录: ├─node_modules //第三方依赖 ├─public //静态资源(不参与打包) └─src├─assets //静态资源├─components //组件├─config //配置├─http //请求方法封装├─layout //页面…...
【ShuQiHere】️ 如何启用 SSH 服务
🛠️ 如何启用 SSH 服务 目录 基础概念 🌱检查是否已安装 SSH 服务 🔍在不同操作系统上安装 SSH 服务 💻 LinuxWindows 11macOS 启动和启用 SSH 服务 🚀配置防火墙以允许 SSH 连接 🔥配置 SSH 服务&#…...
【自动化测试】APP UI 自动化(安卓)-本地环境搭建
一、软件准备及版本介绍 软件版本JAVA-SDK1.8.0_181 python 3.10.10 Android SDK Tools 下最新版本即可,无特殊要求 PyCharm 2023.3.5(下最新版本即可,无特殊要求) 二、安装步骤及环境变量配置 2.1 Java安装及配置 1&am…...
java毕业设计之基于Bootstrap的常州地方旅游管理系统的设计与实现(springboot)
项目简介 基于Bootstrap的常州地方旅游管理系统的设计与实现有下功能: 基于Bootstrap的常州地方旅游管理系统的设计与实现的主要使用者分为用户功能模块和管理员功能模块两大部分,用户可查看景点信息、景点资讯等,注册登录后可进行景点订票…...
《机甲崛起》
第一章:觉醒 在遥远的未来,地球的面貌已被人类科技彻底改变。蓝天被高耸的摩天大楼和闪烁的飞行器撕裂,城市的光辉仿佛能照亮整个星球。然而,繁华背后隐藏着深重的危机:生态环境的恶化、资源的匮乏,已成为…...
Windows10:Linux Reader
Linux Reader Access files and folders on Ext, UFS, HFS, ReiserFS, or APFS file systems from Windows DiskInternals 发布的 Linux Reader 是一款能在 Windows 系统环境下读取 Linux 分区文件的免费软件,提供了资源管理器式的浏览模式。它使用只读模式挂载 L…...
一、k8s快速入门之学习Kubernetes组件基础
一、三个容器管理器平台 Apache MESOS 开源的分布式资源管理框架,被推特选为基础平台,2019年推特换位k8s,MESOS最新版可以在MESOS上管理k8sDOCKER SWARM docker总部发行的,实现docker的集群方案,和docker捆版一起&…...
PostgreSQL 到 PostgreSQL 数据迁移同步
简述 PostgreSQL 是一个历史悠久且广泛使用的数据库,不仅具备标准的关系型数据库能力,还具有相当不错的复杂 SQL 执行能力。用户常常会将 PostgreSQL 应用于在线事务型业务,以及部分数据分析工作,所以 PostgreSQL 到 PostgreSQL …...
RestTemplate 常用方法(提供了多种方法来发送 HTTP 请求)
RestTemplate 是 Spring 框架中用于同步客户端 HTTP 请求的一个类,它提供了多种方法来发送 HTTP 请求。以下是一些常用的 RestTemplate 方法及其代码案例: 1.postForObject() 该方法用于发送 POST 请求,并期望返回一个对象。以下是一个使用…...
常量和变量
常量 常量是指在程序中使用的一些具体的数、字符。在程序运行过程中,其值不能被更改。如123,145.88,m,TRUE等。常量,用于记录程序中不可更改的数据。 分类 1、整型常量,表示整数的常量。 表示形式: 1)十进制形…...
Go语言的使用
在安装Go和配置镜像时,可以根据操作系统和网络环境来选择适合的步骤。以下是详细的安装步骤和镜像配置: 1. 安装Go 1.1 通过官方下载 访问 Go的官方下载页面 下载适合操作系统的安装包(Windows、macOS 或 Linux)。安装包下载完…...
详解CRC校验原理以及FPGA实现
文章目录 一、什么是CRC校验?二、实现CRC校验原理以及步骤2.1 用多项式表示二元码数据2.2 选择一个生成多项式作为校验2.3 计算CRC校验码 三、CRC判断数据是否错误的原理以及步骤3.1 将收到的数据与生成多项式求余3.2 数据发生错误再进行CRC校验判断 四、FPGA实现CR…...
NCNN+OpenCV+Vulkan三件套:Windows环境下的深度学习加速实战教程
NCNNOpenCVVulkan三件套:Windows环境下的深度学习加速实战教程 在深度学习模型部署的战场上,Windows平台往往被开发者视为"次优选择"——直到NCNN、OpenCV和Vulkan这个黄金组合的出现。这个三件套解决方案正在改变游戏规则:NCNN提供…...
2269 上市公司智慧供应链对数字创新的平均处理效应指标【ATT】(2000-2024)
数据来源上市公司年报时间跨度2000-2024区域跨度全国所有上市公司数据格式数据格式为Excel形式数据简介本数据集旨在全面测度中国上市公司智慧供应链建设的政策冲击效应,涵盖了2000年至2024年A股上市公司的长周期面板数据。作为研究数字经济与实体经济深度融合的关键…...
从零开始:使用ecCodes库高效解析GRIB文件
1. 为什么需要ecCodes库处理GRIB文件 第一次接触气象数据时,我被GRIB文件搞得一头雾水。这种二进制格式就像个黑盒子,明明知道里面装着宝贵的温度、气压、风速数据,却不知道怎么取出来。后来发现ecCodes库就像开罐器,能轻松打开这…...
Chandra AI企业知识管理方案:文档智能检索与摘要生成
Chandra AI企业知识管理方案:文档智能检索与摘要生成 1. 引言 企业每天都在产生海量文档——合同、报告、PPT、技术文档...这些宝贵的知识资产往往散落在各处,查找困难,利用率低。传统的关键词搜索就像在黑暗中摸索,找到的文档可…...
商用电子表格:重塑美国经济的隐形力量
电子表格虽不受人喜爱,却是有史以来最成功的应用软件,全球六分之一的人都在使用。它重塑了美国经济,改变了企业的认知与运营方式。不起眼的伟大工具微软 Excel 是最成功的应用软件,全球六分之一的人都在使用它,还决定着…...
Ubuntu22.04微信依赖冲突的终极解决方案
1. 问题现象与原因分析 最近在Ubuntu 22.04上安装微信时,很多朋友都遇到了依赖冲突的问题。具体表现是当你尝试通过命令行安装微信时,系统会提示类似这样的错误信息: 下列软件包有未满足的依赖关系: libldap-2.4-2 : 依赖: libsas…...
4个核心功能实现智能散热:FanControl个性化温控指南
4个核心功能实现智能散热:FanControl个性化温控指南 【免费下载链接】FanControl.Releases This is the release repository for Fan Control, a highly customizable fan controlling software for Windows. 项目地址: https://gitcode.com/GitHub_Trending/fa/F…...
知乎上线求职工具,助力毕业生破困局
知乎上线求职利器,直击毕业生痛点2026届全国普通高校毕业生预计达1270万人,再创历史新高。与此同时,AI技术加速行业重构,部分传统岗位需求收缩,大量毕业生陷入“海投”困境,难以精准定位自身。在此背景下&a…...
UV固化三防漆好用吗?光固化速度与设备要求
UV固化三防漆好用吗?光固化速度与设备要求高效快速的固化优势 UV固化三防漆(也称紫外光固化保形涂层)是一种专为印刷电路板(PCB)设计的保护材料,通过紫外光照射触发光引发剂瞬间聚合,实现快速固…...
避开这3个坑!Cortex-M3/M4使用DWT计数器时的常见错误与解决方法
Cortex-M3/M4开发实战:DWT计数器避坑指南与高阶应用技巧 在嵌入式系统开发中,精确的时间测量往往是性能优化和调试的关键。Cortex-M3/M4内核内置的DWT(Data Watchpoint and Trace)组件,特别是其CYCCNT计数器,为开发者提供了一个零…...
