当前位置: 首页 > 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…...

反向工程与模型迁移:打造未来商品详情API的可持续创新体系

在电商行业蓬勃发展的当下&#xff0c;商品详情API作为连接电商平台与开发者、商家及用户的关键纽带&#xff0c;其重要性日益凸显。传统商品详情API主要聚焦于商品基本信息&#xff08;如名称、价格、库存等&#xff09;的获取与展示&#xff0c;已难以满足市场对个性化、智能…...

基于服务器使用 apt 安装、配置 Nginx

&#x1f9fe; 一、查看可安装的 Nginx 版本 首先&#xff0c;你可以运行以下命令查看可用版本&#xff1a; apt-cache madison nginx-core输出示例&#xff1a; nginx-core | 1.18.0-6ubuntu14.6 | http://archive.ubuntu.com/ubuntu focal-updates/main amd64 Packages ng…...

论文解读:交大港大上海AI Lab开源论文 | 宇树机器人多姿态起立控制强化学习框架(一)

宇树机器人多姿态起立控制强化学习框架论文解析 论文解读&#xff1a;交大&港大&上海AI Lab开源论文 | 宇树机器人多姿态起立控制强化学习框架&#xff08;一&#xff09; 论文解读&#xff1a;交大&港大&上海AI Lab开源论文 | 宇树机器人多姿态起立控制强化…...

图表类系列各种样式PPT模版分享

图标图表系列PPT模版&#xff0c;柱状图PPT模版&#xff0c;线状图PPT模版&#xff0c;折线图PPT模版&#xff0c;饼状图PPT模版&#xff0c;雷达图PPT模版&#xff0c;树状图PPT模版 图表类系列各种样式PPT模版分享&#xff1a;图表系列PPT模板https://pan.quark.cn/s/20d40aa…...

Android第十三次面试总结(四大 组件基础)

Activity生命周期和四大启动模式详解 一、Activity 生命周期 Activity 的生命周期由一系列回调方法组成&#xff0c;用于管理其创建、可见性、焦点和销毁过程。以下是核心方法及其调用时机&#xff1a; ​onCreate()​​ ​调用时机​&#xff1a;Activity 首次创建时调用。​…...

Go 并发编程基础:通道(Channel)的使用

在 Go 中&#xff0c;Channel 是 Goroutine 之间通信的核心机制。它提供了一个线程安全的通信方式&#xff0c;用于在多个 Goroutine 之间传递数据&#xff0c;从而实现高效的并发编程。 本章将介绍 Channel 的基本概念、用法、缓冲、关闭机制以及 select 的使用。 一、Channel…...

MySQL 8.0 事务全面讲解

以下是一个结合两次回答的 MySQL 8.0 事务全面讲解&#xff0c;涵盖了事务的核心概念、操作示例、失败回滚、隔离级别、事务性 DDL 和 XA 事务等内容&#xff0c;并修正了查看隔离级别的命令。 MySQL 8.0 事务全面讲解 一、事务的核心概念&#xff08;ACID&#xff09; 事务是…...

Python+ZeroMQ实战:智能车辆状态监控与模拟模式自动切换

目录 关键点 技术实现1 技术实现2 摘要&#xff1a; 本文将介绍如何利用Python和ZeroMQ消息队列构建一个智能车辆状态监控系统。系统能够根据时间策略自动切换驾驶模式&#xff08;自动驾驶、人工驾驶、远程驾驶、主动安全&#xff09;&#xff0c;并通过实时消息推送更新车…...

深入理解Optional:处理空指针异常

1. 使用Optional处理可能为空的集合 在Java开发中&#xff0c;集合判空是一个常见但容易出错的场景。传统方式虽然可行&#xff0c;但存在一些潜在问题&#xff1a; // 传统判空方式 if (!CollectionUtils.isEmpty(userInfoList)) {for (UserInfo userInfo : userInfoList) {…...

如何在Windows本机安装Python并确保与Python.NET兼容

✅作者简介&#xff1a;2022年博客新星 第八。热爱国学的Java后端开发者&#xff0c;修心和技术同步精进。 &#x1f34e;个人主页&#xff1a;Java Fans的博客 &#x1f34a;个人信条&#xff1a;不迁怒&#xff0c;不贰过。小知识&#xff0c;大智慧。 &#x1f49e;当前专栏…...