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

03-JAVA设计模式-工厂模式详解

工厂模式

工厂设计模式是一种创建型设计模式,它提供了一种封装对象创建过程的机制,将对象的创建与使用分离。
这种设计模式允许我们在不修改客户端代码的情况下引入新的对象类型。
在Java中,工厂设计模式主要有三种形式:简单工厂模式、工厂方法模式和抽象工厂模式。

简单工厂模式

用来生成同一等级结构中的任意产品。

注:对增加新的产品需要修改已有的代码,这违背了面向对象设计原则中的开闭原则(对扩展开放,对修改关闭)

UML

在这里插入图片描述

实现代码

Animal.java

// 定义一个动物的接口
public interface Animal {// 接口中定义一个抽象的方法:叫声void makeSound();
}

Cat.java

// 定义一个实现类实现Animal接口
public class Cat implements Animal{// 猫属于动物:实现发出叫声的接口@Overridepublic void makeSound() {System.out.println("喵喵喵");}
}

Dog.java

// 定义一个实现类实现Animal接口
public class Dog implements Animal{// 狗属于动物:实现发出叫声的接口@Overridepublic void makeSound() {System.out.println("汪汪汪");}
}

SimpleAnimalFactory.java

// 定义一个简单工厂类用于创建动物
public class SimpleAnimalFactory {// 定义一个创建动物的方法用于生产不同的动物的静态方法public static Animal createAnimal(String type) {if ("Cat".equalsIgnoreCase(type)) {return new Cat();}else if ("Dog".equalsIgnoreCase(type)) {return new Dog();}else  {return null;}}
}

TestClient.java

public class TestClient {public static void main(String[] args) {// 根据简单工厂创建不同的动物,执行动作// 生产一个CatAnimal cat = SimpleAnimalFactory.createAnimal("cat");cat.makeSound();// 生产一个DogAnimal dog = SimpleAnimalFactory.createAnimal("Dog");dog.makeSound();}
}

执行结果:

在这里插入图片描述

结论:

简单工厂好处在于,对于客户端调用时,我们不需要关心具体实现,只需要调用工厂方法,传入参数获取我们需要返回的结果即可。

但是对于同一个产品(动物),如果我们进行新增(猪),则必须要修改Factory中createAnimal(String type)方法。因此违背了开闭原则

工厂方法模式

用来生产同一等级结构中的固定产品。

支持增加任意产品,满足开闭原则,但设计相对于简单工厂复杂一些

UML

在这里插入图片描述

实现代码

Product.java

// 定义一个产品接口
public interface Product {//定义一个抽象的使用的方法void use();
}

ProductA.java

// ProductA实现Product接口
public class ProductA implements Product{@Overridepublic void use() {System.out.println("ProductA 使用了");}
}

ProductB.java

// ProductB实现Product接口
public class ProductB implements Product{@Overridepublic void use() {System.out.println("ProductB 使用了");}
}

ProductFactory.java

// 定义一个ProductFactory工厂接口
public interface ProductFactory {// 接口中定义一个创建Product的方法Product createProduct();
}

ProductAFactory.java

// 创建一个ProductA的工厂,实现ProductFactory接口,用于生产ProductA
public class ProductAFactory implements ProductFactory{@Overridepublic Product createProduct() {return new ProductA();}
}

ProductBFactory.java

// 创建一个ProductB的工厂,实现ProductFactory接口,用于生产ProductB
public class ProductBFactory implements ProductFactory{@Overridepublic Product createProduct() {return new ProductB();}
}

TestClient.java

public class TestClient {public static void main(String[] args) {// 创建ProductAProduct product1 = new ProductAFactory().createProduct();product1.use();// 创建ProductBProduct product2 = new ProductBFactory().createProduct();product2.use();}
}

执行结果:

在这里插入图片描述

从工厂方式模式,我们可以看出,我们可以任意增加同一产品,而不会影响到原来已有产品
(创建一个产品C继承Product接口,创建一个产品C的Factory类生产C,使用是通过相应Factory调用生产C即可)。
如果产品中新增一个方法,则所有实现了Product接口的方法都必须修改相应方法。

抽象工厂模式

用来生产不同产品族的全部产品。

对增加新的产品无能为力,支持增加产品族

UML

在这里插入图片描述

实现代码

Engine.java

// 定义发动机接口
public interface Engine {// 定义发动机 发动方法void run();// 定义发动机 停止方法void stop();
}

HighEndEngine.java

// 创建一个高端发动机实现发动机
public class HighEndEngine implements Engine{@Overridepublic void run() {System.out.println("高端发动机-跑的快");}@Overridepublic void stop() {System.out.println("高端发动机-刹车性能强");}
}

LowEndEngine.java

// 创建一个低端发动机实现发动机
public class LowEndEngine implements Engine{@Overridepublic void run() {System.out.println("低端发动机-跑的慢");}@Overridepublic void stop() {System.out.println("低端发动机-刹车性能弱");}
}

CarBody.java

// 定义一个车身接口
public interface CarBody {// 定义一个乘坐的方法void ride();
}

HighEndCarBody.java

// 创建一个高端车身实现车身
public class HighEndCarBody implements CarBody{@Overridepublic void ride() {System.out.println("高端车身-奢华-安全");}
}

LowEndCarBody.java

// 创建一个低端车身实现车身
public class LowEndCarBody implements CarBody{@Overridepublic void ride() {System.out.println("低端车身-朴素-看起来安全");}
}

Tyre.java

// 定义一个轮胎接口
public interface Tyre {// 定义轮胎转动的方法void run();
}

HighEndTyre.java

// 创建一个高端轮胎实现轮胎
public class HighEndTyre implements Tyre{@Overridepublic void run() {System.out.println("高端轮胎-太空材料-安全-耐磨");}
}

LowEndTyre.java

// 创建一个低端轮胎实现轮胎
public class LowEndTyre implements Tyre{@Overridepublic void run() {System.out.println("低端轮胎-普通材料-易磨损");}
}

CarFactory.java

// 定义Car的接口
public interface CarFactory {// 创建发动机Engine engine();// 创建车身CarBody carBody();// 创建轮胎Tyre tyre();
}

HighEndCarBody.java

// 高端汽车工厂实现汽车工厂
public class HighEndCarFactory implements CarFactory{@Overridepublic Engine engine() {return new HighEndEngine();}@Overridepublic CarBody carBody() {return new HighEndCarBody();}@Overridepublic Tyre tyre() {return new HighEndTyre();}
}

LowEndCarFactory.java

// 低端汽车工厂实现汽车工厂
public class LowEndCarFactory implements CarFactory{@Overridepublic Engine engine() {return new LowEndEngine();}@Overridepublic CarBody carBody() {return new LowEndCarBody();}@Overridepublic Tyre tyre() {return new LowEndTyre();}
}

TestClient.java

public class TestClient {public static void main(String[] args) {// 使用高端汽车工厂类 创建高端汽车HighEndCarFactory highEndCar = new HighEndCarFactory();highEndCar.engine().stop();highEndCar.carBody().ride();highEndCar.tyre().run();System.out.println("==========================");// 使用低端汽车工厂类 创建低端汽车LowEndCarFactory lowEndCar = new LowEndCarFactory();lowEndCar.engine().stop();lowEndCar.carBody().ride();lowEndCar.tyre().run();}
}

执行结果:

在这里插入图片描述

抽象工厂,不可以增加产品(比如:CarFactory一旦定下了,如果我们要新增新的部件则所有实现CarFactory的类都需实现该方法)。
但是抽象工厂,可以根据已有的接口,创建更多的产品族(比如:定义一个中端汽车工厂,调用高端发动机,低端轮胎,低端车身,等任意组合成新的Factory)

对比及应用场景

简单工厂模式

  • 优点:
    • 实现了对象的创建和使用的责任分割,客户端只需要传入正确的参数,就可以获取需要的对象,无需知道创建细节。
    • 工厂类中有必要的判断逻辑,可以决定根据当前的参数创建对应的产品实例,客户端可以免除直接创建产品对象的责任。
  • 缺点:
    • 工厂类职责过重,如果产品种类增加,工厂类的代码会变得庞大且复杂,不利于维护。
    • 简单工厂模式违背了开放封闭原则,因为每次增加新产品时,都需要修改工厂类的代码。
  • 适用场景:
    • 创建对象较少,且对象的创建逻辑不复杂时。
    • 客户端不关心对象的创建过程,只关心使用对象时。

工厂方法模式

  • 优点:
    • 将对象的创建推迟到子类中进行,使得类的实例化更加灵活和可扩展。
    • 降低了客户端与具体产品类之间的耦合度,客户端只需要知道对应的工厂,无需知道具体的产品类。
  • 缺点:
    • 增加了系统的抽象性和理解难度,需要引入额外的工厂接口和工厂类。
    • 如果产品类较少,使用工厂方法模式可能会增加不必要的复杂性。
  • 适用场景:
    • 需要创建大量相似对象时,可以使用工厂方法模式来简化对象的创建过程。
    • 当一个类需要由其子类来指定创建哪个对象时,可以使用工厂方法模式。
    • 但实际开发中,简单工厂比工厂方法使用的更多

抽象工厂模式

  • 优点:
    • 提供了创建一系列相关或相互依赖对象的接口,无需指定它们具体的类。
    • 增加了系统的灵活性和可扩展性,可以通过更换不同的工厂来实现不同的产品族。
  • 缺点:
    • 规定了所有可能被创建的产品集合,产品族中扩展新的产品困难。
    • 如果产品族中的产品较少,使用抽象工厂模式可能会导致代码冗余和复杂性增加。
  • 适用场景:
    • 当需要创建一组相互关联或相互依赖的对象时,可以使用抽象工厂模式。
    • 当一个系统需要独立地变化其创建的对象时,抽象工厂模式是一个很好的选择。

gitee源码

git clone https://gitee.com/dchh/JavaStudyWorkSpaces.git

相关文章:

03-JAVA设计模式-工厂模式详解

工厂模式 工厂设计模式是一种创建型设计模式,它提供了一种封装对象创建过程的机制,将对象的创建与使用分离。 这种设计模式允许我们在不修改客户端代码的情况下引入新的对象类型。 在Java中,工厂设计模式主要有三种形式:简单工厂…...

百度文心大模型推理成本降至1% / 马斯克起诉OpenAI |魔法半周报

我有魔法✨为你劈开信息大海❗ 高效获取AIGC的热门事件🔥,更新AIGC的最新动态,生成相应的魔法简报,节省阅读时间👻 🔥资讯预览 百度文心大模型推理成本降至1%,与三星、荣耀等企业达成合作 马斯…...

Struts2的入门:新建项目——》导入jar包——》jsp,action,struts.xml,web.xml——》在项目运行

文章目录 配置环境tomcat 新建项目导入jar包新建jsp界面新建action类新建struts.xml,用来配置action文件配置Struts2的核心过滤器:web.xml 启动测试给一个返回界面在struts.xml中配置以实现页面的跳转:result再写个success.jsp最后在项目运行 配置环境 …...

git 标签功能操作以及回退

Git 标签功能允许开发者为特定的提交打上标签,以便后续能够方便地引用这些提交。标签通常用于标记重要的版本或里程碑,例如软件发布的版本号。与分支不同,标签指向的是固定的提交,一旦设置,就不能轻易更改。下面是一些…...

利用python实现文字转语音

代码如下: import pathlib import tkinter as tk import tkinter.ttk as ttk import tkinter.filedialog as filedialog import tkinter.messagebox as msgbox import pyttsx3class Application(tk.Tk):def __init__(self):super().__init__()self.title("文本…...

拾光坞N3 ARM 虚拟主机 i茅台项目

拾光坞N3 在Dcoker部署i茅台案例 OS:Ubuntu 22.04.1 LTS aarch64 cpu:RK3566 ram:2G 部署流程——》mysql——》java8——》redis——》nginx mysql # 依赖 apt update apt install -y net-tools apt install -y libaio* # 下载mysql wg…...

docker安装nacos,单例模式(standalone),使用mysql数据库

文章目录 前言安装创建文件夹"假装"安装一下nacos拷贝文件夹删除“假装”安装的nacos容器生成nacos所需的mysql表获取mysql-schema.sql文件创建一个mysql的schema 重新生成新的nacos容器 制作docker-compose.yaml文件查看网站 前言 此处有本人写得简易版本安装&…...

【运输层】传输控制协议 TCP

目录 1、传输控制协议 TCP 概述 (1)TCP 的特点 (2)TCP 连接中的套接字概念 2、可靠传输的工作原理 (1)停止等待协议 (2)连续ARQ协议 3、TCP 报文段的首部格式 1、传输控制协议…...

深入浅出 -- 系统架构之Keepalived搭建双机热备

Keepalived重启脚本双机热备搭建 ①首先创建一个对应的目录并下载keepalived安装包(提取码:s6aq)到Linux中并解压: [rootlocalhost]# mkdir /soft/keepalived && cd /soft/keepalived [rootlocalhost]# wget https://www.keepalived.…...

如何做好产业园运营?树莓集团:响应政府号召,规划,注重大局观

随着经济的发展和产业结构的调整,产业园区的建设和发展已经成为推动地方经济的重要力量。如何做好产业园运营,提高行业竞争力,现已成为了一个亟待解决的问题。树莓集团作为一家有着丰富产业园运营经验的企业,积极响应政府号召&…...

NIO与BIO

当谈到 Java 网络编程时,经常会听到两个重要的概念:BIO(Blocking I/O,阻塞 I/O)和 NIO(Non-blocking I/O,非阻塞 I/O)。它们都是 Java 中用于处理 I/O 操作的不同编程模型。 一、介…...

YOLOv5实战记录05 Pyside6可视化界面

个人打卡,慎看。 指路大佬:【手把手带你实战YOLOv5-入门篇】YOLOv5 Pyside6可视化界面_哔哩哔哩_bilibili 零、虚拟环境迁移路径后pip报错解决 yolov5-master文件夹我换位置后,无法pip install了。解决如下: activate.bat中修改…...

HTML5.Canvas简介

1. Canvas.getContext getContext(“2d”)是Canvas元素的方法,用于获取一个用于绘制2D图形的绘图上下文对象。在给定的代码中,首先通过getElementById方法获取id为"myCanvas"的Canvas元素,然后使用getContext(“2d”)方法获取该Ca…...

excel统计分析——多项式回归

参考资料:生物统计学 多项式回归属于单变量曲线回归,但其形式和求解方法与多元线性回归相似。多项式回归的数学模型为: 令,,,,则 由于X不可逆,两边同时乘以X得,&#xff…...

SQLyog连接数据库8.0版本解析错误问题解决方案

问题描述: 解决方案: alter userrootlocalhostidentified with mysql_native_password by 密码; 再次连接就可以了。...

【数据库】SQL简介

SQL(Structured Query Language,结构化查询语言)是一种用于管理关系型数据库管理系统(RDBMS)的标准化语言。它用于访问和操作数据库中的数据,执行各种任务,如插入、更新、删除和检索数据&#x…...

AWS入门实践-利用S3构建一个静态网站

使用Amazon S3托管静态网站是一个流行的选择,因为它简单、成本效益高,并且易于维护。静态网站由不含服务器端脚本的文件组成,如HTML、CSS和JavaScript文件。下面是使用S3托管静态网站的操作步骤: 如果大家没有AWS免费账号&#x…...

使用Linux strace追踪系统调用: 一个详细指南

使用Linux strace追踪系统调用: 一个详细指南 Linux strace是一个强大的命令行工具,用于监视和调试进程中发生的系统调用和信号。它对于系统管理员和开发人员来说是理解程序行为和解决问题的重要工具。 什么是strace? strace是一种跟踪运行中的进程执…...

python 笔记

文章目录 pdbpdb开始调试pythonpdb设置断点单步执行进入到函数的内部执行到下一个断点或程序结束调用栈查看命令查看当前函数调用堆栈向上一层函数查看调用堆栈查看源代码 importimport 用法 numpy导入numpy模块numpy常用函数np.argmaxnp.sum range生成连续序列生成不连续序列 …...

软考 系统架构设计师系列知识点之数据库基本概念(4)

接前一篇文章:软考 系统架构设计师系列知识点之数据库基本概念(3) 所属章节: 第6章. 数据库设计基础知识 第1节 数据库基本概念 6.1.3 数据库管理系统 DBMS(DataBase Management System,数据库管理系统&am…...

AI-调查研究-01-正念冥想有用吗?对健康的影响及科学指南

点一下关注吧!!!非常感谢!!持续更新!!! 🚀 AI篇持续更新中!(长期更新) 目前2025年06月05日更新到: AI炼丹日志-28 - Aud…...

【Python】 -- 趣味代码 - 小恐龙游戏

文章目录 文章目录 00 小恐龙游戏程序设计框架代码结构和功能游戏流程总结01 小恐龙游戏程序设计02 百度网盘地址00 小恐龙游戏程序设计框架 这段代码是一个基于 Pygame 的简易跑酷游戏的完整实现,玩家控制一个角色(龙)躲避障碍物(仙人掌和乌鸦)。以下是代码的详细介绍:…...

脑机新手指南(八):OpenBCI_GUI:从环境搭建到数据可视化(下)

一、数据处理与分析实战 (一)实时滤波与参数调整 基础滤波操作 60Hz 工频滤波:勾选界面右侧 “60Hz” 复选框,可有效抑制电网干扰(适用于北美地区,欧洲用户可调整为 50Hz)。 平滑处理&…...

中南大学无人机智能体的全面评估!BEDI:用于评估无人机上具身智能体的综合性基准测试

作者:Mingning Guo, Mengwei Wu, Jiarun He, Shaoxian Li, Haifeng Li, Chao Tao单位:中南大学地球科学与信息物理学院论文标题:BEDI: A Comprehensive Benchmark for Evaluating Embodied Agents on UAVs论文链接:https://arxiv.…...

《Playwright:微软的自动化测试工具详解》

Playwright 简介:声明内容来自网络,将内容拼接整理出来的文档 Playwright 是微软开发的自动化测试工具,支持 Chrome、Firefox、Safari 等主流浏览器,提供多语言 API(Python、JavaScript、Java、.NET)。它的特点包括&a…...

多模态商品数据接口:融合图像、语音与文字的下一代商品详情体验

一、多模态商品数据接口的技术架构 (一)多模态数据融合引擎 跨模态语义对齐 通过Transformer架构实现图像、语音、文字的语义关联。例如,当用户上传一张“蓝色连衣裙”的图片时,接口可自动提取图像中的颜色(RGB值&…...

Python实现prophet 理论及参数优化

文章目录 Prophet理论及模型参数介绍Python代码完整实现prophet 添加外部数据进行模型优化 之前初步学习prophet的时候,写过一篇简单实现,后期随着对该模型的深入研究,本次记录涉及到prophet 的公式以及参数调优,从公式可以更直观…...

ardupilot 开发环境eclipse 中import 缺少C++

目录 文章目录 目录摘要1.修复过程摘要 本节主要解决ardupilot 开发环境eclipse 中import 缺少C++,无法导入ardupilot代码,会引起查看不方便的问题。如下图所示 1.修复过程 0.安装ubuntu 软件中自带的eclipse 1.打开eclipse—Help—install new software 2.在 Work with中…...

拉力测试cuda pytorch 把 4070显卡拉满

import torch import timedef stress_test_gpu(matrix_size16384, duration300):"""对GPU进行压力测试,通过持续的矩阵乘法来最大化GPU利用率参数:matrix_size: 矩阵维度大小,增大可提高计算复杂度duration: 测试持续时间(秒&…...

tree 树组件大数据卡顿问题优化

问题背景 项目中有用到树组件用来做文件目录,但是由于这个树组件的节点越来越多,导致页面在滚动这个树组件的时候浏览器就很容易卡死。这种问题基本上都是因为dom节点太多,导致的浏览器卡顿,这里很明显就需要用到虚拟列表的技术&…...