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

工厂方法模式与抽象工厂模式

工厂方法模式 (Factory Method)

定义: 工厂方法模式是一种创建型设计模式,它定义了一个用于创建对象的接口,但让子类决定实例化哪个类。工厂方法将类的实例化推迟到子类。

优点

  1. 解耦:客户端代码与具体的产品类解耦,只依赖于产品的接口。
  2. 可扩展性:新增产品只需实现相应的工厂方法,无需修改现有代码。
  3. 灵活性:可以根据具体需求选择不同的产品。

应用场景

  • 当一个类不知道它所需要的对象的类时。
  • 当一个类希望通过子类来指定所创建的对象时。
  • 当类的实例化过程非常复杂时。

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;
}

总结

在这个示例中,工厂方法模式允许我们通过不同的工厂类创建不同类型的汽车。客户端代码只需要依赖于 CarFactoryCar 接口,而不需要了解具体的汽车实现。这种解耦设计提高了代码的灵活性和可维护性,便于未来的扩展。

  • 抽象工厂模式

抽象工厂模式 (Abstract Factory)

定义: 抽象工厂模式是一种创建型设计模式,它提供一个接口,用于创建一系列相关或相互依赖的对象,而无需指定它们的具体类。通过这种方式,抽象工厂模式可以使客户端代码与具体产品的实现解耦。

优点

  1. 解耦:客户端不需要依赖具体产品类,可以通过抽象接口进行交互。
  2. 可扩展性:如果需要增加新的产品,只需实现新的工厂和产品类,无需修改现有代码。
  3. 一致性:确保产品之间的兼容性和一致性。

应用场景

  • 当系统需要独立于其产品的创建、组合和表示时。
  • 当系统需要根据不同的配置来生成一系列相关的产品时。

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) 定义&#xff1a; 工厂方法模式是一种创建型设计模式&#xff0c;它定义了一个用于创建对象的接口&#xff0c;但让子类决定实例化哪个类。工厂方法将类的实例化推迟到子类。 优点&#xff1a; 解耦&#xff1a;客户端代码与具体的产品类解耦…...

「Math」初等数学知识点大纲(占位待处理)

✨博客主页何曾参静谧的博客&#x1f4cc;文章专栏「C/C」C/C程序设计&#x1f4da;全部专栏「VS」Visual Studio「C/C」C/C程序设计「UG/NX」BlockUI集合「Win」Windows程序设计「DSA」数据结构与算法「UG/NX」NX二次开发「QT」QT5程序设计「File」数据文件格式「PK」Parasoli…...

百元高性价比头戴式降噪耳机选哪款?四款平价性价比品牌别错过!

随着科技的发展&#xff0c;现在的头戴式耳机真的是越来越多样了&#xff0c;很多的朋友在选购耳机的时候&#xff0c;不知道哪一款头戴式耳机的性价比较高&#xff0c;究竟百元高性价比头戴式降噪耳机选哪款&#xff1f;身为一名数码爱好者&#xff0c;这里就给大家推带来四款…...

vue3 setup写不写到标签上的区别

在vue3种setup的写法&#xff0c;可以单独写setup()也可以写到script标签中&#xff0c;当然我们推荐后面这种 他的好处有很多&#xff0c;代码也简洁很多。1、属性和方法无需return&#xff0c;可直接使用 /*原先*/ <script> import { defineComponent } from "v…...

【论文解读】EdgeYOLO:一种边缘实时目标检测器(附论文地址)

论文地址&#xff1a;https://arxiv.org/pdf/2302.07483 这篇文章的标题是《EdgeYOLO: An Edge-Real-Time Object Detector》&#xff0c;由中国北京理工大学的Shihan Liu、Junlin Zha、Jian Sun、Zhuo Li和Gang Wang共同撰写。这篇论文提出了一个基于最新YOLO框架的高效、低复…...

xlwings,让excel飞起来!

excel已经成为必不可少的数据处理软件&#xff0c;几乎天天在用。python有很多支持操作excel的第三方库&#xff0c;xlwings是其中一个。 关于xlwings xlwings开源免费&#xff0c;能够非常方便的读写Excel文件中的数据&#xff0c;并且能够进行单元格格式的修改。 xlwings还…...

C语言学习,标准库 <stddef.h>

<stddef.h> C 标准库中头文件&#xff0c;它定义了一些常用的类型定义和宏。这些定义通常用于指针操作、数组处理和其他需要固定大小数据类型的场合。 size_t&#xff1a; 这是一个无符号整数类型&#xff0c;用于表示对象的大小&#xff08;以字节为单位&#xff09;。…...

PyQt5实战——操作台打印重定向,主界面以及stacklayout使用(四)

个人博客&#xff1a;苏三有春的博客 系类往期文章&#xff1a; PyQt5实战——多脚本集合包&#xff0c;前言与环境配置&#xff08;一&#xff09; PyQt5实战——多脚本集合包&#xff0c;UI以及工程布局&#xff08;二&#xff09; PyQt5实战——多脚本集合包&#xff0c;程序…...

React + Vite + TypeScript + React router项目搭建教程

一、创建项目 运行项目 二、目录结构 项目目录&#xff1a; ├─node_modules //第三方依赖 ├─public //静态资源&#xff08;不参与打包&#xff09; └─src├─assets //静态资源├─components //组件├─config //配置├─http //请求方法封装├─layout //页面…...

【ShuQiHere】️ 如何启用 SSH 服务

&#x1f6e0;️ 如何启用 SSH 服务 目录 基础概念 &#x1f331;检查是否已安装 SSH 服务 &#x1f50d;在不同操作系统上安装 SSH 服务 &#x1f4bb; LinuxWindows 11macOS 启动和启用 SSH 服务 &#x1f680;配置防火墙以允许 SSH 连接 &#x1f525;配置 SSH 服务&#…...

【自动化测试】APP UI 自动化(安卓)-本地环境搭建

一、软件准备及版本介绍 软件版本JAVA-SDK1.8.0_181 python 3.10.10 Android SDK Tools 下最新版本即可&#xff0c;无特殊要求 PyCharm 2023.3.5&#xff08;下最新版本即可&#xff0c;无特殊要求&#xff09; 二、安装步骤及环境变量配置 2.1 Java安装及配置 1&am…...

java毕业设计之基于Bootstrap的常州地方旅游管理系统的设计与实现(springboot)

项目简介 基于Bootstrap的常州地方旅游管理系统的设计与实现有下功能&#xff1a; 基于Bootstrap的常州地方旅游管理系统的设计与实现的主要使用者分为用户功能模块和管理员功能模块两大部分&#xff0c;用户可查看景点信息、景点资讯等&#xff0c;注册登录后可进行景点订票…...

《机甲崛起》

第一章&#xff1a;觉醒 在遥远的未来&#xff0c;地球的面貌已被人类科技彻底改变。蓝天被高耸的摩天大楼和闪烁的飞行器撕裂&#xff0c;城市的光辉仿佛能照亮整个星球。然而&#xff0c;繁华背后隐藏着深重的危机&#xff1a;生态环境的恶化、资源的匮乏&#xff0c;已成为…...

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 分区文件的免费软件&#xff0c;提供了资源管理器式的浏览模式。它使用只读模式挂载 L…...

一、k8s快速入门之学习Kubernetes组件基础

一、三个容器管理器平台 Apache MESOS 开源的分布式资源管理框架&#xff0c;被推特选为基础平台&#xff0c;2019年推特换位k8s&#xff0c;MESOS最新版可以在MESOS上管理k8sDOCKER SWARM docker总部发行的&#xff0c;实现docker的集群方案&#xff0c;和docker捆版一起&…...

PostgreSQL 到 PostgreSQL 数据迁移同步

简述 PostgreSQL 是一个历史悠久且广泛使用的数据库&#xff0c;不仅具备标准的关系型数据库能力&#xff0c;还具有相当不错的复杂 SQL 执行能力。用户常常会将 PostgreSQL 应用于在线事务型业务&#xff0c;以及部分数据分析工作&#xff0c;所以 PostgreSQL 到 PostgreSQL …...

RestTemplate 常用方法(提供了多种方法来发送 HTTP 请求)

RestTemplate 是 Spring 框架中用于同步客户端 HTTP 请求的一个类&#xff0c;它提供了多种方法来发送 HTTP 请求。以下是一些常用的 RestTemplate 方法及其代码案例&#xff1a; 1.postForObject() 该方法用于发送 POST 请求&#xff0c;并期望返回一个对象。以下是一个使用…...

常量和变量

常量 常量是指在程序中使用的一些具体的数、字符。在程序运行过程中&#xff0c;其值不能被更改。如123,145.88,m,TRUE等。常量&#xff0c;用于记录程序中不可更改的数据。 分类 1、整型常量&#xff0c;表示整数的常量。 表示形式&#xff1a;   1&#xff09;十进制形…...

Go语言的使用

在安装Go和配置镜像时&#xff0c;可以根据操作系统和网络环境来选择适合的步骤。以下是详细的安装步骤和镜像配置&#xff1a; 1. 安装Go 1.1 通过官方下载 访问 Go的官方下载页面 下载适合操作系统的安装包&#xff08;Windows、macOS 或 Linux&#xff09;。安装包下载完…...

详解CRC校验原理以及FPGA实现

文章目录 一、什么是CRC校验&#xff1f;二、实现CRC校验原理以及步骤2.1 用多项式表示二元码数据2.2 选择一个生成多项式作为校验2.3 计算CRC校验码 三、CRC判断数据是否错误的原理以及步骤3.1 将收到的数据与生成多项式求余3.2 数据发生错误再进行CRC校验判断 四、FPGA实现CR…...

Mac视频预览终极指南:QuickLookVideo让你的Finder焕然一新

Mac视频预览终极指南&#xff1a;QuickLookVideo让你的Finder焕然一新 【免费下载链接】QuickLookVideo This package allows macOS Finder to display thumbnails, static QuickLook previews, cover art and metadata for most types of video files. 项目地址: https://gi…...

昇思大模型垂域模型

昇思 MindSpore 垂域模型是基于通用大模型基座 行业数据微调 领域技术增强构建的行业专用 AI 模型&#xff0c;依托 MindSpore Transformers 套件与昇腾硬件&#xff0c;在医疗、金融、电力、法律、工业等领域实现深度落地&#xff0c;兼顾通用能力与行业专业性&#xff0c;训…...

终极免费Windows音频调校指南:用Equalizer APO解锁专业音质

终极免费Windows音频调校指南&#xff1a;用Equalizer APO解锁专业音质 【免费下载链接】equalizerapo Equalizer APO mirror 项目地址: https://gitcode.com/gh_mirrors/eq/equalizerapo 你是否对电脑的音质总是不满意&#xff1f;无论是听音乐、看电影还是玩游戏&…...

CTF逆向新手必看:用Python脚本搞定AES、Z3、Base64这些常见加密(附避坑指南)

CTF逆向实战手册&#xff1a;Python脚本自动化破解高频加密算法 1. 逆向工程中的加密算法挑战 在CTF逆向题目中&#xff0c;加密算法就像迷宫中的隐形墙壁&#xff0c;看似无形却处处设障。最近三年赛事数据显示&#xff0c;AES、Base系列和Z3约束求解三类题型出现频率合计占比…...

无王无帝定乾坤,来自田间第一人 凰标重塑新风骨

一、破题&#xff1a;王权不是答案旧认知新真相山河气运系于帝王扭转乾坤藏于民间位高者裁定是非布衣亦可定乾坤权贵定义风骨凰标重塑精神二、旧世风骨之殇等级枷锁 王权为纲 → 尊卑为界 → 精神镣铐千年。世俗偏见 财富分贵贱 → 地位论高低 → 人心逐利忘本。结局 风骨消磨 …...

Visual C++运行库合集:一站式解决Windows应用程序依赖问题的终极指南

Visual C运行库合集&#xff1a;一站式解决Windows应用程序依赖问题的终极指南 【免费下载链接】vcredist AIO Repack for latest Microsoft Visual C Redistributable Runtimes 项目地址: https://gitcode.com/gh_mirrors/vc/vcredist 还在为"缺少msvcp140.dll&qu…...

试0998y测试0998y试0998y测试0998y试0998y测试0998y试0998y测试0998y

试0998y测试0998y试0998y测试0998y试0998y测试0998y...

【DBC专题】-12-基于Cantools的CAN/CANFD DBC文件自动化C代码生成实战指南

1. 环境准备与工具链搭建 第一次接触CAN总线开发时&#xff0c;我被DBC文件到C代码的手动转换折磨得够呛。直到发现Cantools这个神器&#xff0c;才真正体会到什么叫"一劳永逸"。这个Python工具链能自动将DBC描述文件转换为可直接编译的C代码&#xff0c;特别适合需要…...

别再折腾Yum源了!用Docker Desktop 10分钟搞定Vulhub靶场(附一键脚本)

10分钟极速搭建Vulhub靶场&#xff1a;Docker Desktop全攻略 在网络安全学习和渗透测试实践中&#xff0c;Vulhub作为开箱即用的漏洞环境集合&#xff0c;已经成为安全研究者的必备工具。然而&#xff0c;传统的Linux环境配置过程往往让初学者望而却步——复杂的Yum源配置、漫…...

使用Taotoken后我们如何清晰观测各模型的用量与延迟表现

&#x1f680; 告别海外账号与网络限制&#xff01;稳定直连全球优质大模型&#xff0c;限时半价接入中。 &#x1f449; 点击领取海量免费额度 使用Taotoken后我们如何清晰观测各模型的用量与延迟表现 当团队在项目中同时接入多个大语言模型时&#xff0c;一个常见的困扰随之…...