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

设计模式之工厂模式:从汽车工厂到代码工厂

在这里插入图片描述

~犬📰余~

“我欲贱而贵,愚而智,贫而富,可乎?
曰:其唯学乎”

在这里插入图片描述

工厂模式概述

想象一下你走进一家4S店准备买车。作为顾客,你不需要知道汽车是如何被制造出来的,你只需要告诉销售顾问:“我想要一辆轿车"或"我想要一辆SUV”,他们就会为你安排相应的车型。这就是工厂模式的核心思想 —— 将对象的创建过程封装起来,让客户端与具体产品的创建逻辑解耦。
在软件开发中,工厂模式就像一个虚拟的4S店。当你的程序需要一个对象时,不需要直接使用new关键字来创建,而是通过工厂类来获取。这样做的好处是,如果将来需要更换对象的创建方式,或者增加新的对象类型,只需要修改工厂类的代码,而不会影响到使用这些对象的代码。
工厂模式通过将对象的创建和使用分离,实现了面向对象设计的一个重要原则:开闭原则(对扩展开放,对修改关闭)。就像4S店可以不断引入新的车型,而不会影响到已有客户的使用体验一样。

工厂模式分类

简单工厂模式

简单工厂就像一家小型的4S店,店里只有一个销售顾问,他根据顾客的需求直接安排相应的车型。在代码实现中,我们会创建一个工厂类,它提供一个创建对象的方法,根据传入的参数来决定创建哪种具体的产品对象。
如:

// 汽车接口
public interface Car {void drive();
}// 具体汽车类
public class SedanCar implements Car {@Overridepublic void drive() {System.out.println("驾驶轿车");}
}public class SUVCar implements Car {@Overridepublic void drive() {System.out.println("驾驶SUV");}
}// 简单工厂类
public class CarFactory {public static Car createCar(String type) {if ("sedan".equals(type)) {return new SedanCar();} else if ("suv".equals(type)) {return new SUVCar();}throw new IllegalArgumentException("不支持的车型类型");}
}

这种模式的使用非常简单:

Car sedanCar = CarFactory.createCar("sedan");
sedanCar.drive();Car suvCar = CarFactory.createCar("suv");
suvCar.drive();

执行结果:
在这里插入图片描述
如上示例,在简单工厂模式中,CarFactory类负责创建所有类型的汽车。这种方式适用于产品种类相对固定,创建逻辑不会经常变化的场景。就像一家小型4S店,经营的车型比较固定,不会经常变动。

工厂方法模式

工厂方法模式就像一个汽车制造集团,下设多个专门的工厂,每个工厂专注于生产一种类型的汽车。比如轿车工厂专门生产轿车,SUV工厂专门生产SUV。这样每个工厂都可以根据自己的特点来优化生产流程。
在代码中,我们会定义一个抽象的工厂接口,然后针对不同的产品创建专门的工厂类:

// 抽象工厂
public abstract class CarFactory {abstract Car createCar();
}// 具体工厂
public class SedanFactory extends CarFactory {@Overridepublic Car createCar() {return new SedanCar();}
}public class SUVFactory extends CarFactory {@Overridepublic Car createCar() {return new SUVCar();}
}

使用时,我们先选择对应的工厂,然后创建产品:

CarFactory sedanFactory = new SedanFactory();
Car sedan = sedanFactory.createCar();
sedan.drive();CarFactory suvFactory = new SUVFactory();
Car suv = suvFactory.createCar();
suv.drive();

运行结果:
在这里插入图片描述
与简单工厂相比,工厂方法模式将不同产品的创建过程分散到不同的工厂类中,每个工厂类都专注于创建自己的产品。这样在需要增加新产品时,只需要添加新的工厂类,而不需要修改现有的工厂类,更好地符合开闭原则。就像汽车集团可以轻松增加新的生产线,而不会影响现有工厂的运作。

抽象工厂模式

抽象工厂模式就像一个汽车制造集团不仅生产整车,还要生产发动机、车身等配套零部件。每个工厂都能生产一整套相关的产品,这些产品之间相互配套,形成一个产品族。比如轿车工厂生产轿车发动机和轿车车身,SUV工厂生产SUV发动机和SUV车身。如:

// 抽象产品
public interface Engine {void start();
}public interface Body {void assemble();
}// 具体产品
public class SedanEngine implements Engine {@Overridepublic void start() {System.out.println("轿车发动机启动");}
}public class SUVEngine implements Engine {@Overridepublic void start() {System.out.println("SUV发动机启动");}
}public class SedanBody implements Body {@Overridepublic void assemble() {System.out.println("组装轿车车身");}
}public class SUVBody implements Body {@Overridepublic void assemble() {System.out.println("组装SUV车身");}
}// 抽象工厂
public interface CarFactory {Engine createEngine();Body createBody();
}// 具体工厂
public class SedanFactory implements CarFactory {@Overridepublic Engine createEngine() {return new SedanEngine();}@Overridepublic Body createBody() {return new SedanBody();}
}public class SUVFactory implements CarFactory {@Overridepublic Engine createEngine() {return new SUVEngine();}@Overridepublic Body createBody() {return new SUVBody();}
}

测试代码如下:

// 生产轿车系列产品
System.out.println("=== 生产轿车系列 ===");
CarFactory sedanFactory = new SedanFactory();
Engine sedanEngine = sedanFactory.createEngine();
Body sedanBody = sedanFactory.createBody();// 组装轿车
sedanEngine.start();  // 输出:轿车发动机启动
sedanBody.assemble(); // 输出:组装轿车车身System.out.println("\n=== 生产SUV系列 ===");
// 生产SUV系列产品
CarFactory suvFactory = new SUVFactory();
Engine suvEngine = suvFactory.createEngine();
Body suvBody = suvFactory.createBody();// 组装SUV
suvEngine.start();    // 输出:SUV发动机启动
suvBody.assemble();   // 输出:组装SUV车身

运行结果:
在这里插入图片描述

工厂模式优缺点

  • 简单工厂模式就像一个小型4S店,结构简单,使用方便。它的优点是实现简单,客户端只需要知道产品的参数就可以了;缺点是工厂类的职责相对过重,增加新产品时需要修改工厂类的代码,违反了开闭原则。
  • 工厂方法模式像一个汽车制造集团下的多个专业工厂,每个工厂专注于一种产品。它的优点是符合开闭原则,扩展性好,增加新产品只需要增加相应的工厂类;缺点是类的数量会随着产品的增加而增加,增加了系统的复杂度。
  • 抽象工厂模式则像一个全产业链的汽车制造集团,可以生产多个产品族。它的优点是能够保证一系列相关产品的配套性,支持产品族的扩展;缺点是抽象层次较高,增加新的产品部件时麻烦,需要修改所有的工厂类。

如何选择工厂模式的实现方式

  • 如果你的应用场景简单,产品种类较少且相对稳定,可以选择简单工厂模式。就像开一家小型4S店,只经营几种固定车型。
  • 如果产品种类会经常变动,建议使用工厂方法模式。这就像汽车制造集团可以根据市场需求灵活增加新的生产线。
  • 如果你需要创建一系列相互关联的产品,那么抽象工厂模式是最好的选择。这适合于像汽车制造这样需要协调多个配套零部件生产的场景。

总结

工厂模式是一种创建型设计模式,它通过将对象的创建与使用分离,提供了一种灵活的对象创建方式。简单工厂适合简单场景,工厂方法适合单个产品的变化,抽象工厂适合产品族的扩展。理解这三种模式的特点和使用场景,可以帮助我们在实际开发中选择最适合的实现方式。
在这里插入图片描述

关注犬余,共同进步

技术从此不孤单

相关文章:

设计模式之工厂模式:从汽车工厂到代码工厂

~犬📰余~ “我欲贱而贵,愚而智,贫而富,可乎? 曰:其唯学乎” 工厂模式概述 想象一下你走进一家4S店准备买车。作为顾客,你不需要知道汽车是如何被制造出来的,你只需要告诉销售顾问&a…...

人脸识别Adaface之libpytorch部署

目录 1. libpytorch下载2. Adaface模型下载3. 模型转换4. c推理4.1 前处理4.2 推理4.3 编译运行4.3.1 写CMakeLists.txt4.3.2 编译4.3.3 运行 1. libpytorch下载 参考: https://blog.csdn.net/liang_baikai/article/details/127849577 下载完成后,将其解…...

vue3+echarts+websocket分时图与K线图实时推送

一、父组件代码&#xff1a; <template> <div class"chart-box" v-loading"loading"> <!-- tab导航栏 --> <div class"tab-box"> <div class"tab-list"> <div v-for"(item, index) in tabList…...

小程序开发实战项目:构建简易待办事项列表

随着移动互联网的飞速发展&#xff0c;小程序以其便捷性、即用即走的特点&#xff0c;成为了连接用户与服务的重要桥梁。无论是电商平台的购物助手&#xff0c;还是餐饮行业的点餐系统&#xff0c;小程序都在各个领域发挥着巨大的作用。 小程序开发基础 1. 小程序简介 小程序是…...

SD Express 卡漏洞导致笔记本电脑和游戏机遭受内存攻击

Positive Technologies 最近发布的一份报告揭示了一个名为 DaMAgeCard 的新漏洞&#xff0c;攻击者可以利用该漏洞利用 SD Express 内存卡直接访问系统内存。 该漏洞利用了 SD Express 中引入的直接内存访问 (DMA) 功能来加速数据传输速度&#xff0c;但也为对支持该标准的设备…...

前端node环境安装:nvm安装详细教程(安装nvm、node、npm、cnpm、yarn及环境变量配置)

需求&#xff1a;在做前端开发的时候&#xff0c;有的时候 这个项目需要 node 14 那个项目需要 node 16&#xff0c;我们也不能卸载 安装 。这岂不是很麻烦。这个时候 就需要 一个工具 来管理我们的 node 版本和 npm 版本。 下面就分享一个 nvm 工具 用来管理 node 版本。 这个…...

java之集合(详细-Map,Set,List)

1集合体系概述 1.1集合的概念 集合是一种容器&#xff0c;用来装数据的&#xff0c;类似于数组&#xff0c;但集合的大小可变&#xff0c;开发中也非常常用。 1.2集合分类 集合分为单列集合和多列集合 Collection代表单列集合&#xff0c;每个元素&#xff08;数据&#xff…...

常见LeetCode-Saw200

用来记录需要知道见过的题型&#xff1a; LeetCode2-两数相加 说明&#xff1a;以链表的形势给了你每个位的数字&#xff0c;而且是逆序&#xff0c;直接从开头&#xff08;个位&#xff09;遍历相加。带上进位即可。有一个为空就直接计算另一个和进位。 LeetCode-3.无重复字符…...

Unity 制作一个视频播放器(打包后,可在外部编辑并放置新的视频)

效果展示&#xff1a; 在这里&#xff0c;我把视频名称&#xff08;Json&#xff09;和对应的视频资源都放在了StreamingAssets文件夹下&#xff0c;以便于打包后&#xff0c;客户还可以自己在外部增加、删除、修改对应的视频资料。 如有需要&#xff0c;请联细抠抠。...

MySQL-SQL语句

文章目录 一. SQL语句介绍二. SQL语句分类1. 数据定义语言&#xff1a;简称DDL(Data Definition Language)2. 数据操作语言&#xff1a;简称DML(Data Manipulation Language)3. 数据查询语言&#xff1a;简称DQL(Data Query Language)4. 数据控制语言&#xff1a;简称DCL(Data …...

腾讯微信大数据面试题及参考答案

DNS 协议是否使用 UDP? DNS(Domain Name System)协议主要使用 UDP(User Datagram Protocol),但也会使用 TCP(Transmission Control Protocol)。 UDP 是一种无连接的传输协议,它的特点是简单、高效。DNS 在进行域名解析时,大部分情况下使用 UDP。因为 UDP 的开销小,对…...

Python跳动的爱心

系列文章 序号直达链接表白系列1Python制作一个无法拒绝的表白界面2Python满屏飘字表白代码3Python无限弹窗满屏表白代码4Python李峋同款可写字版跳动的爱心5Python流星雨代码6Python漂浮爱心代码7Python爱心光波代码8Python普通的玫瑰花代码9Python炫酷的玫瑰花代码10Python多…...

计算机启动过程 | Linux 启动流程

注&#xff1a;本文为“计算机启动、 Linux 启动”相关文章合辑。 替换引文部分不清晰的图。 探索计算机的启动过程 Aleksandr Goncharov 2023/04/21 很多人对计算机的启动方式很感兴趣。只要设备开启&#xff0c;这就是魔法开始和持续的地方。在本文中&#xff0c;我们将概…...

反射简单介绍

反射就是从类里拿东西 有的人可能会想为什么不能用io流&#xff0c;从上往下一行一行的读也能获取类中的信息&#xff0c;为什么要用反射呢&#xff1f; 假如我们io流&#xff0c;从左到右一行一行的读取数据&#xff0c;如果碰到局部变量和成员变量同名&#xff0c;怎么区分&a…...

工具篇--GitHub Desktop 使用

文章目录 前言一、GitHub Desktop 的使用&#xff1a;1.1 通过官网下载GitHub Desktop和安装&#xff1a;1.2 安装和使用&#xff1a;1.2.1 填充自己的标识&#xff1a;1.2.3 克隆项目&#xff1a;1.2.4 git 常用忽略项配置&#xff1a; 二、代码的更新和提交&#xff1a;2.1 代…...

单臂路由配置

知识点 单臂路由指在路由器上的一个接口配置子接口&#xff08;逻辑接口&#xff09;来实现不同vlan间通信 路由器上的每个物理接口都可以配置多个子接口&#xff08;逻辑接口&#xff09; 公司的财务部、技术部和业务部有多台计算机&#xff0c;它们使用一台二层交换机进行互…...

河工oj第七周补题题解2024

A.GO LecturesⅠ—— Victory GO LecturesⅠ—— Victory - 问题 - 软件学院OJ 代码 统计 #include<bits/stdc.h> using namespace std;double b, w;int main() {for(int i 1; i < 19; i ) {for(int j 1; j < 19; j ) {char ch; cin >> ch;if(ch B) b …...

卷积的数学原理与作用

一、一维卷积 &#xff08;一&#xff09;定义 数学定义 给定一个输入序列 x [ x 1 , x 2 , ⋯ , x n ] x [x_1,x_2,\cdots,x_n] x[x1​,x2​,⋯,xn​] 和一个卷积核&#xff08;滤波器&#xff09; k [ k 1 , k 2 , ⋯ , k m ] k [k_1,k_2,\cdots,k_m] k[k1​,k2​,⋯,…...

路由介绍.

RIB和FIB Routing Information Base&#xff08;RIB&#xff09;&#xff0c;即路由信息库&#xff0c;是存储在路由器或联网计算机中的一个电子表格或类数据库&#xff0c;它保存着指向特定网络地址的路径信息&#xff0c;包括路径的路由度量值。RIB的主要目标是实现路由协议…...

CTFshow-命令执行(Web29-40)

CTFshow-命令执行(Web29-40) CTFWeb-命令执行漏洞过滤的绕过姿势_绕过空格过滤-CSDN博客 总结rce&#xff08;远程代码执行各种sao姿势&#xff09;绕过bypass_远程命令执行绕过-CSDN博客 对比两者的源代码&#xff0c;我们发现&#xff0c;cat指令把flag.php的内容导出后依…...

rknn优化教程(二)

文章目录 1. 前述2. 三方库的封装2.1 xrepo中的库2.2 xrepo之外的库2.2.1 opencv2.2.2 rknnrt2.2.3 spdlog 3. rknn_engine库 1. 前述 OK&#xff0c;开始写第二篇的内容了。这篇博客主要能写一下&#xff1a; 如何给一些三方库按照xmake方式进行封装&#xff0c;供调用如何按…...

ESP32 I2S音频总线学习笔记(四): INMP441采集音频并实时播放

简介 前面两期文章我们介绍了I2S的读取和写入&#xff0c;一个是通过INMP441麦克风模块采集音频&#xff0c;一个是通过PCM5102A模块播放音频&#xff0c;那如果我们将两者结合起来&#xff0c;将麦克风采集到的音频通过PCM5102A播放&#xff0c;是不是就可以做一个扩音器了呢…...

如何将联系人从 iPhone 转移到 Android

从 iPhone 换到 Android 手机时&#xff0c;你可能需要保留重要的数据&#xff0c;例如通讯录。好在&#xff0c;将通讯录从 iPhone 转移到 Android 手机非常简单&#xff0c;你可以从本文中学习 6 种可靠的方法&#xff0c;确保随时保持连接&#xff0c;不错过任何信息。 第 1…...

Python爬虫(二):爬虫完整流程

爬虫完整流程详解&#xff08;7大核心步骤实战技巧&#xff09; 一、爬虫完整工作流程 以下是爬虫开发的完整流程&#xff0c;我将结合具体技术点和实战经验展开说明&#xff1a; 1. 目标分析与前期准备 网站技术分析&#xff1a; 使用浏览器开发者工具&#xff08;F12&…...

Mac软件卸载指南,简单易懂!

刚和Adobe分手&#xff0c;它却总在Library里给你写"回忆录"&#xff1f;卸载的Final Cut Pro像电子幽灵般阴魂不散&#xff1f;总是会有残留文件&#xff0c;别慌&#xff01;这份Mac软件卸载指南&#xff0c;将用最硬核的方式教你"数字分手术"&#xff0…...

DBAPI如何优雅的获取单条数据

API如何优雅的获取单条数据 案例一 对于查询类API&#xff0c;查询的是单条数据&#xff0c;比如根据主键ID查询用户信息&#xff0c;sql如下&#xff1a; select id, name, age from user where id #{id}API默认返回的数据格式是多条的&#xff0c;如下&#xff1a; {&qu…...

CRMEB 框架中 PHP 上传扩展开发:涵盖本地上传及阿里云 OSS、腾讯云 COS、七牛云

目前已有本地上传、阿里云OSS上传、腾讯云COS上传、七牛云上传扩展 扩展入口文件 文件目录 crmeb\services\upload\Upload.php namespace crmeb\services\upload;use crmeb\basic\BaseManager; use think\facade\Config;/*** Class Upload* package crmeb\services\upload* …...

IoT/HCIP实验-3/LiteOS操作系统内核实验(任务、内存、信号量、CMSIS..)

文章目录 概述HelloWorld 工程C/C配置编译器主配置Makefile脚本烧录器主配置运行结果程序调用栈 任务管理实验实验结果osal 系统适配层osal_task_create 其他实验实验源码内存管理实验互斥锁实验信号量实验 CMISIS接口实验还是得JlINKCMSIS 简介LiteOS->CMSIS任务间消息交互…...

基于matlab策略迭代和值迭代法的动态规划

经典的基于策略迭代和值迭代法的动态规划matlab代码&#xff0c;实现机器人的最优运输 Dynamic-Programming-master/Environment.pdf , 104724 Dynamic-Programming-master/README.md , 506 Dynamic-Programming-master/generalizedPolicyIteration.m , 1970 Dynamic-Programm…...

10-Oracle 23 ai Vector Search 概述和参数

一、Oracle AI Vector Search 概述 企业和个人都在尝试各种AI&#xff0c;使用客户端或是内部自己搭建集成大模型的终端&#xff0c;加速与大型语言模型&#xff08;LLM&#xff09;的结合&#xff0c;同时使用检索增强生成&#xff08;Retrieval Augmented Generation &#…...