【设计模式】工厂模式

首先了解一下什么是工厂方法模式?

工厂方法模式(Factory Method Pattern)是一种创建型设计模式,它提供了一种方法来封装对象的创建逻辑。具体来说,它通过定义一个创建对象的接口(即工厂方法),但将具体的对象实例化工作推迟到子类中完成。这样,客户端代码可以在不知道具体类的情况下创建对象,从而实现创建与使用的分离。


作用

工厂方法模式在软件设计中有以下几个主要作用:

  1. 解耦
    将对象的创建与使用分离,客户端无需了解具体类的实现细节,只需通过工厂方法获取对象即可。这降低了代码的耦合度。

  2. 扩展性
    当需要添加新的对象类型时,只需增加新的具体工厂类和产品类,而无需修改现有代码,符合之前我们提到的“开闭原则”(对扩展开放,对修改关闭)(SOLID的O)。

  3. 灵活性
    通过工厂方法,系统可以在运行时动态决定实例化哪个类,增加了程序的灵活性。


用法

工厂方法模式适用于以下场景:

  • 当一个类无法预先知道需要创建的具体对象类型时。
  • 当希望由子类决定创建哪种对象时。
  • 当需要将对象的创建职责委托给多个子类中的某一个时。

C++ 示例

下面通过一个完整的 C++ 示例来说明工厂方法模式。我们以创建不同类型车辆(汽车和卡车)为例。
具体的UML图如下:

工厂方法示例UML图

1. 定义产品接口

首先,定义一个抽象基类 Vehicle,它声明了所有车辆必须实现的方法。

#include <iostream>class Vehicle {
public:virtual void drive() const = 0;  // 纯虚函数,所有子类必须实现virtual ~Vehicle() = default;    // 虚析构函数,确保正确释放资源
};
2. 实现具体产品类

接下来,创建两个具体产品类 CarTruck,它们继承自 Vehicle,并实现 drive 方法。

class Car : public Vehicle {
public:void drive() const override {std::cout << "Driving a car." << std::endl;}
};class Truck : public Vehicle {
public:void drive() const override {std::cout << "Driving a truck." << std::endl;}
};
3. 定义工厂接口

然后,定义一个抽象工厂类 VehicleFactory,它包含一个纯虚函数 createVehicle,用于创建 Vehicle 对象的实例。

class VehicleFactory {
public:virtual Vehicle* createVehicle() const = 0;  // 工厂方法,子类必须实现virtual ~VehicleFactory() = default;         // 虚析构函数
};
4. 实现具体工厂类

再创建两个具体工厂类 CarFactoryTruckFactory,它们继承自 VehicleFactory,并实现 createVehicle 方法,分别返回 CarTruck 实例。

class CarFactory : public VehicleFactory {
public:Vehicle* createVehicle() const override {return new Car();}
};class TruckFactory : public VehicleFactory {
public:Vehicle* createVehicle() const override {return new Truck();}
};
5. 使用工厂方法

在客户端代码中,通过工厂对象创建车辆实例,而无需直接实例化具体类。

int main() {// 创建汽车工厂并生产汽车VehicleFactory* carFactory = new CarFactory();  //注意这里含有纯虚函数的抽象类,是不可以初始化的,但是它的指针可以接受子类new出来的对象Vehicle* car = carFactory->createVehicle();car->drive();  // 输出: Driving a car.delete car;    // 释放车辆对象delete carFactory;  // 释放工厂对象// 创建卡车工厂并生产卡车VehicleFactory* truckFactory = new TruckFactory();Vehicle* truck = truckFactory->createVehicle();truck->drive();  // 输出: Driving a truck.delete truck;    // 释放车辆对象delete truckFactory;  // 释放工厂对象return 0;
}

运行以上代码,输出如下:

Driving a car.
Driving a truck.

详细解释

让我们逐步分析这个示例的每个组成部分:

  1. 产品接口(Vehicle)

    • Vehicle 是一个抽象基类,定义了所有具体产品(CarTruck)必须实现的接口(drive 方法)。
    • 使用纯虚函数(= 0)确保子类必须提供实现。
    • 虚析构函数确保通过基类指针删除对象时能正确释放资源。
  2. 具体产品(Car、Truck)

    • CarTruck 是具体的产品类,继承自 Vehicle,并实现了 drive 方法。
    • 它们代表系统中实际的对象类型,提供了具体的功能实现。
  3. 工厂接口(VehicleFactory)

    • VehicleFactory 是一个抽象工厂类,定义了工厂方法 createVehicle
    • 该方法是纯虚的,意味着具体工厂类必须实现它来创建具体产品。
  4. 具体工厂(CarFactory、TruckFactory)

    • CarFactoryTruckFactory 是具体工厂类,分别负责创建 CarTruck 对象。
    • 通过重写 createVehicle,它们封装了对象的创建逻辑。
  5. 客户端代码

    • 客户端通过 VehicleFactory 接口调用 createVehicle 方法来创建对象。
    • 客户端无需知道具体的产品类(CarTruck)或其实现细节,只需与工厂交互即可。
    • 这种方式实现了创建与使用的解耦。

模式优势

  • 解耦:客户端代码不直接依赖具体产品类(CarTruck),而是通过工厂接口操作。
  • 扩展性:如果需要添加新的车辆类型(如 Motorcycle),只需新增 Motorcycle 类和对应的 MotorcycleFactory 类,无需修改现有代码。
  • 灵活性:可以在运行时根据需要选择不同的工厂,动态创建不同类型的对象。

总结

工厂方法模式通过将对象的创建逻辑封装在子类中,实现了对象创建与使用的分离。它在 C++ 中通过抽象工厂类和具体工厂类的配合,提供了灵活、可扩展的创建机制。在上述示例中,我们通过创建车辆的工厂方法模式展示了其核心思想:定义接口,推迟实现,解耦使用。这种模式特别适合需要动态创建多种对象类型的场景,是设计模式中非常实用的一种方法。

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

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

相关文章

centos 7 部署FTP 服务用shell 脚本搭建

#!/bin/bash# 检查是否以root身份运行脚本 if [ "$EUID" -ne 0 ]; thenecho "请以root身份运行此脚本。"exit 1 fi# 安装vsftpd yum install -y vsftpd# 启动vsftpd服务并设置开机自启 systemctl start vsftpd systemctl enable vsftpd# 配置防火墙以允许F…

基于Spring Boot的个性化商铺系统的设计与实现(LW+源码+讲解)

专注于大学生项目实战开发,讲解,毕业答疑辅导&#xff0c;欢迎高校老师/同行前辈交流合作✌。 技术范围&#xff1a;SpringBoot、Vue、SSM、HLMT、小程序、Jsp、PHP、Nodejs、Python、爬虫、数据可视化、安卓app、大数据、物联网、机器学习等设计与开发。 主要内容&#xff1a;…

AI(DeepSeek、ChatGPT)、Python、ArcGIS Pro多技术融合下的空间数据分析、建模与科研绘图及论文写作

人工智能&#xff08;AI&#xff09;与ArcGIS Pro的结合&#xff0c;为空间数据处理和分析开辟了前所未有的创新路径。AI通过强大的数据挖掘、深度学习及自动化能力&#xff0c;可高效处理海量、多源、异构的空间数据&#xff0c;极大提升了分析效率与决策支持能力。而ArcGIS P…

2025最新3个wordpress好用的主题

红色大气的wordpress企业主题&#xff0c;适合服务行业的公司搭建企业官方网站使用。是一款专为中小企业和个人开发者设计的WordPress主题&#xff0c;旨在提供专业的网站构建解决方案。 通过此WordPress主题&#xff0c;用户可以轻松创建和维护一个专业的企业网站&#xff0c…

Spring AI Alibaba AudioModel使用

一、AudioModel简介 1、AudioModel 当前&#xff0c;Spring AI Alibaba 支持以下两种通义语音模型的适配&#xff0c;分别是&#xff1a; 文本生成语音 SpeechModel&#xff0c;对应于 OpenAI 的 Text-To-Speech (TTS) API录音文件生成文字 DashScopeAudioTranscriptionMode…

时隔多年,终于给它换了皮肤,并正式起了名字

时隔多年&#xff0c;终于更新了直播推流软件UI&#xff0c;并正式命名为FlashEncoder。软件仍使用MFC框架&#xff0c;重绘了所有用到的控件&#xff0c;可以有效保证软件性能&#xff0c;也便于后续进一步优化。 下载地址&#xff1a;https://download.csdn.net/download/Xi…

Python备赛笔记2

1.区间求和 题目描述 给定a1……an一共N个整数&#xff0c;有M次查询&#xff0c;每次需要查询区间【L,R】的和。 输入描述: 第一行包含两个数&#xff1a;N,M 第二行输入N个整数 接下来的M行&#xff0c;每行有两个整数&#xff0c;L R&#xff0c;中间用空格隔开&…

各类神经网络学习:(四)RNN 循环神经网络(下集),pytorch 版的 RNN 代码编写

上一篇下一篇RNN&#xff08;中集&#xff09;待编写 代码详解 pytorch 官网主要有两个可调用的模块&#xff0c;分别是 nn.RNNCell 和 nn.RNN &#xff0c;下面会进行详细讲解。 RNN 的同步多对多、多对一、一对多等等结构都是由这两个模块实现的&#xff0c;只需要将对输入…

python每日十题(10)

在Python语言中&#xff0c;源文件的扩展名&#xff08;后缀名&#xff09;一般使用.py。 保留字&#xff0c;也称关键字&#xff0c;是指被编程语言内部定义并保留使用的标识符。Python 3.x有35个关键字&#xff0c;分别为&#xff1a;and&#xff0c;as&#xff0c;assert&am…

Harbor镜像仓库迁移与高可用集群搭建HTTPS实现实战指南

实验环境 Ubuntu22.04操作系统 registry节点 10.0.0.91 master节点 10.0.0.92 backup节点 10.0.0.93 在企业信息化建设的不同演进阶段&#xff0c;私有镜像仓库的选型策略存在显著差异。近期主导完成某企业级容器镜像仓库升级项目&#xff0c;成功实现Docker Registry至Ha…

【Python】pillow库学习笔记3-Image.mode

提取颜色通道时&#xff0c;偶然换了个图片&#xff0c;结果在在运行代码时一直报错&#xff1a; from PIL import Image im Image.open(city2.png) r,g,b im.split() om Image.merge("RGB", (b,g,r)) om.save(cBGR.jpg)Traceback (most recent call last): File…

PDF打开密码教程:让您的文档更安全

在数字化办公时代&#xff0c;PDF 文件常包含敏感信息&#xff0c;这时候&#xff0c;给PDF文件设置打开密码就成了一种有效的保护措施。这样&#xff0c;只有输入正确密码的人才能查看内容&#xff0c;大大提高了文件的安全性。如果您对这方面不清楚&#xff0c;就来看看小编分…

SOFAActs 介绍-01-白盒测试框架 overview

前言 大家好&#xff0c;我是老马。 sofastack 其实出来很久了&#xff0c;第一次应该是在 2022 年左右开始关注&#xff0c;但是一直没有深入研究。 最近想学习一下 SOFA 对于生态的设计和思考。 sofaboot 系列 SOFABoot-00-sofaboot 概览 SOFABoot-01-蚂蚁金服开源的 s…

Snipaste软件出现测量像素不准的问题

最近写一些前端布局的时候发现使用snipaste测量dom元素大小的时候出现和实际不符的情况。我平时写代码的时候是笔记本和一个显示屏&#xff0c;在笔记本上测量的时候发现总是和实际大小不符合&#xff0c;而在显示屏上测量的时候却并无差错&#xff0c;真是奇了怪了。 后来发现…

笔试专题(三)

文章目录 字符串中找出连续最长的数字串题解代码 拼三角题解代码 字符串中找出连续最长的数字串 题目链接 题解 1. 考察双指针 模拟 2. 算法思路&#xff1a;给定一个i 0&#xff0c;让i&#xff0c;如果遇到数字字符就创建一个变量j i&#xff0c;让j去遍历&#xff0c…

基于vue.js开发的家庭装修管理系统开发与设计(源码+lw+部署文档+讲解),源码可白嫖!

摘要 本家庭装修管理系统采用B/S架构&#xff0c;数据库是MySQL&#xff0c;网站的搭建与开发采用了先进的Node.js语言进行编写&#xff0c;使用了VUE框架。该系统从两个对象&#xff1a;由管理员和用户来对系统进行设计构建。用户的功能包括&#xff1a;注册、登录、浏览首页…

NAT网络地址转换与内网穿透

一、背景 前一篇文章提到PCDN&#xff0c; 也就是p2p技术CDN技术进行融合。 P2P技术有利于文件的快速分发。我们的CDN在控制节点分发数据的时候&#xff0c;向边缘节点传输数据&#xff0c;也是一种分发&#xff0c;还有各边缘节点强制同步数据等等&#xff0c;如果结合P2P技术…

【开源宝藏】30天学会CSS - DAY9 第九课 牛顿摆动量守恒动画

以下是一份逐步拆解教程&#xff0c;带你从零理解并复刻这个牛顿摆&#xff08;Pendulum of Newton&#xff09;动画效果&#xff0c;这是一个经典的物理演示模型&#xff0c;现在通过纯 HTML 和 CSS 实现出来&#xff0c;视觉效果炫酷、结构简洁。 &#x1f3af; 动画效果说明…

Chat2DB:一款强大的数据库管理工具,AI助力高效查询与分析

AI技术可谓是日新月异&#xff0c;其已经融入到社会的方方面面&#xff0c;今天就给大家分享一款数据库SQL客户端工具&#xff1a;Chat2DB。 1 简介 Chat2DB是一款开源的数据库管理工具&#xff0c;集成了AI 智能辅助功能&#xff0c;支持自然语言生成 SQL&#xff0c;帮助开发…

安全上网沙箱:多方面解决政企私的上网问题

在数字化的浪潮中&#xff0c;网络已成为我们工作与生活不可或缺的一部分。然而&#xff0c;网络的便捷也伴随着诸多安全隐患&#xff0c;尤其是对于企业、个人以及政企机构而言&#xff0c;安全上外网成为了至关重要的课题。 隔离保护&#xff1a;构建安全堡垒 沙箱技术在内网…