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

GPT带我学-设计模式-工厂模式

1 你好,请问你知道设计模式的工厂模式吗

当然知道,工厂模式是一种创建型设计模式,它提供了一种创建对象的方式,而不需要暴露对象创建的逻辑细节。工厂模式通过使用工厂类来创建对象,从而将对象的实例化逻辑与客户端代码解耦。

在工厂模式中,通常存在一个抽象工厂类,该抽象工厂类定义了创建对象的接口,具体的创建逻辑由其具体实现的工厂类来实现。客户端通过调用工厂类的方法来创建对象,而无需知道具体的创建细节,只需要知道对象所属的抽象类型即可。

工厂模式有多种变体,例如简单工厂模式工厂方法模式抽象工厂模式等。每种变体都有其特定的应用场景和用法。

工厂模式的主要优点是可以降低对象的耦合性,提高代码的灵活性和可扩展性。另外,在需要修改对象的创建逻辑时,只需要修改具体的工厂类而无需修改客户端代码。

希望以上回答对你有帮助。

2 请你介绍一下工厂模式

工厂模式是一种创建型设计模式,它提供了一种创建对象的方式,而不需要暴露对象创建的逻辑细节。工厂模式通过使用工厂类来创建对象,从而将对象的实例化逻辑与客户端代码解耦。

工厂模式通常包括以下角色:

  • 抽象工厂(Abstract Factory):定义了创建对象的接口,通常是一个抽象类或接口,该接口包含了创建对象的方法。
  • 具体工厂(Concrete Factory):继承自抽象工厂,实现了创建具体对象的方法。
  • 抽象产品(Abstract Product):定义了产品对象的接口,通常是一个抽象类或接口。
  • 具体产品(Concrete Product):实现了抽象产品接口的具体对象。

工厂模式的流程如下:

  1. 客户端通过调用工厂类的方法来创建对象,而无需知道具体的创建细节。
  2. 工厂类根据客户端的请求,使用相应的创建逻辑来创建具体对象。
  3. 工厂类返回创建的对象给客户端,完成对象的创建过程。

工厂模式的优点包括:

  1. 降低对象的耦合性:客户端只需要知道抽象类型,而无需关心具体的对象创建细节。
  2. 提高代码的灵活性和可扩展性:当需要添加新的对象时,只需要添加具体工厂类和具体产品类即可,而无需修改客户端代码。
  3. 隐藏复杂的创建逻辑:将对象的创建逻辑封装在工厂类中,使客户端代码更加简洁和易于理解。

工厂模式有多种变体,例如简单工厂模式、工厂方法模式和抽象工厂模式等。每种变体都有其特定的应用场景和用法。
总之,工厂模式是一种常用的设计模式,用于将对象的创建逻辑与客户端代码分离,提高代码的可维护性和可扩展性。

3 工厂模式可以分成几种

工厂模式主要可以分为三种:

  • 简单工厂模式(Simple Factory Pattern):由一个工厂类根据传入的参数决定创建哪一种产品类的实例。
  • 工厂方法模式(Factory Method Pattern):定义一个创建产品的接口,由子类去具体实现产品的创建逻辑。
  • 抽象工厂模式(Abstract Factory Pattern):提供一个创建一系列相关或依赖对象的接口,而无需指定具体类。抽象工厂模式通常使用工厂方法来实现。

4 请使用java写一个简单工厂的例子

下面是一个使用Java实现简单工厂模式的例子:

首先,我们需要定义一个产品接口(Product),以及两个具体产品类(ConcreteProduct1和ConcreteProduct2):

// 产品接口
public interface Product {void use();
}// 具体产品类1
public class ConcreteProduct1 implements Product {@Overridepublic void use() {System.out.println("使用具体产品1");}
}// 具体产品类2
public class ConcreteProduct2 implements Product {@Overridepublic void use() {System.out.println("使用具体产品2");}
}

接下来,我们需要定义一个工厂类(Factory)实现简单工厂模式,根据传入的参数创建对应的产品实例:

public class Factory {public static Product createProduct(String type) {if (type.equalsIgnoreCase("Product1")) {return new ConcreteProduct1();} else if (type.equalsIgnoreCase("Product2")) {return new ConcreteProduct2();}throw new IllegalArgumentException("Unsupported product type: " + type);}
}

在客户端代码中,我们可以通过工厂类创建具体的产品对象:

public class Client {public static void main(String[] args) {Product product1 = Factory.createProduct("Product1");product1.use();Product product2 = Factory.createProduct("Product2");product2.use();}
}

运行Client类,输出结果为:

使用具体产品1
使用具体产品2

以上就是一个使用简单工厂模式的示例,通过工厂类根据传入的参数创建对应的产品实例,实现了解耦和灵活性。

5 你的这个例子有点抽象,我希望你能举一个更贴近生活的例子

当然,我可以给你一个更贴近生活的例子。我们以一个购物网站为例,假设有三种商品:手机、电脑和衣服。通过简单工厂模式来创建商品对象。

首先,定义一个商品接口(Product),以及三个具体商品类(Phone、Computer和Clothes):

// 商品接口
public interface Product {void showInfo();
}// 手机类
public class Phone implements Product {@Overridepublic void showInfo() {System.out.println("这是一部手机");}
}// 电脑类
public class Computer implements Product {@Overridepublic void showInfo() {System.out.println("这是一台电脑");}
}// 衣服类
public class Clothes implements Product {@Overridepublic void showInfo() {System.out.println("这是一件衣服");}
}

接下来,定义一个简单工厂类(ProductFactory)用于创建商品对象:

public class ProductFactory {public static Product createProduct(String type) {if (type.equalsIgnoreCase("phone")) {return new Phone();} else if (type.equalsIgnoreCase("computer")) {return new Computer();} else if (type.equalsIgnoreCase("clothes")) {return new Clothes();}throw new IllegalArgumentException("Unsupported product type: " + type);}
}

在客户端代码中,我们可以通过工厂类创建具体的商品对象:

public class Client {public static void main(String[] args) {Product phone = ProductFactory.createProduct("phone");phone.showInfo();Product computer = ProductFactory.createProduct("computer");computer.showInfo();Product clothes = ProductFactory.createProduct("clothes");clothes.showInfo();}
}

运行Client类,输出结果为:

这是一部手机
这是一台电脑
这是一件衣服

6 继续使用这个例子,写一下工厂方法模式的代码

好的,接下来使用工厂方法模式来重新设计购物网站的例子。

首先,我们定义一个商品接口(Product):

// 商品接口
public interface Product {void showInfo();
}

然后,针对每种商品,创建一个具体的商品类实现该接口:

// 手机类
public class Phone implements Product {@Overridepublic void showInfo() {System.out.println("这是一部手机");}
}// 电脑类
public class Computer implements Product {@Overridepublic void showInfo() {System.out.println("这是一台电脑");}
}// 衣服类
public class Clothes implements Product {@Overridepublic void showInfo() {System.out.println("这是一件衣服");}
}

接下来,定义一个抽象工厂类(AbstractFactory),其中包含了一个抽象方法用于创建具体的商品对象:

public abstract class AbstractFactory {public abstract Product createProduct();
}

然后,为每种商品类型,创建对应的具体工厂类(PhoneFactory、ComputerFactory和ClothesFactory),分别实现抽象工厂类并完成具体的产品创建:

// 手机工厂类
public class PhoneFactory extends AbstractFactory {@Overridepublic Product createProduct() {return new Phone();}
}// 电脑工厂类
public class ComputerFactory extends AbstractFactory {@Overridepublic Product createProduct() {return new Computer();}
}// 衣服工厂类
public class ClothesFactory extends AbstractFactory {@Overridepublic Product createProduct() {return new Clothes();}
}

最后,在客户端代码中,我们可以使用具体的工厂类来创建相应的商品对象:

public class Client {public static void main(String[] args) {AbstractFactory phoneFactory = new PhoneFactory();Product phone = phoneFactory.createProduct();phone.showInfo();AbstractFactory computerFactory = new ComputerFactory();Product computer = computerFactory.createProduct();computer.showInfo();AbstractFactory clothesFactory = new ClothesFactory();Product clothes = clothesFactory.createProduct();clothes.showInfo();}
}

运行Client类,输出结果为:

这是一部手机
这是一台电脑
这是一件衣服

通过工厂方法模式,我们可以根据具体的工厂类来创建对应的商品对象,实现了解耦和灵活性。每个具体工厂类只负责创建特定类型的商品,使得代码更加清晰和可扩展。

简单工厂方法是将所有产品的生产都放进一个工厂中。而工厂方法模式为每种产品都创建了一个工厂类。在客户端中创建工厂之后,直接调用createProduct()方法就能生产出工厂对应的产品了,不需要再传入产品参数。但问题是,每添加一种产品,就要增加一个工厂类。

7 继续使用这个例子,实现抽象工厂模式

好的,接下来使用抽象工厂模式来重新设计购物网站的例子。

首先,我们定义一个抽象工厂接口(AbstractFactory):

// 抽象工厂接口
public interface AbstractFactory {Product createProduct();Shipping createShipping();
}

然后,针对每种商品,创建一个具体的商品类实现商品接口(Product):

// 商品接口
public interface Product {void showInfo();
}// 手机类
public class Phone implements Product {@Overridepublic void showInfo() {System.out.println("这是一部手机");}
}// 电脑类
public class Computer implements Product {@Overridepublic void showInfo() {System.out.println("这是一台电脑");}
}// 衣服类
public class Clothes implements Product {@Overridepublic void showInfo() {System.out.println("这是一件衣服");}
}

接下来,添加了快递物流运输的方式。针对每种物流方式,创建一个具体的物流类实现物流接口(Shipping):

// 物流接口
public interface Shipping {void ship();
}
// 快递物流类
public class ExpressShipping implements Shipping {@Overridepublic void ship() {System.out.println("使用快递进行运输");}
}// 自提物流类
public class PickupShipping implements Shipping {@Overridepublic void ship() {System.out.println("自提,无需运输");}
}

为了实现抽象工厂模式,我们需要为每种商品类型和物流方式,创建对应的具体工厂类(PhoneFactory、ComputerFactory、ClothesFactory),分别实现抽象工厂接口并完成具体的产品创建:

// 手机工厂类
public class PhoneFactory implements AbstractFactory {@Overridepublic Product createProduct() {return new Phone();}@Overridepublic Shipping createShipping() {return new ExpressShipping();}
}// 电脑工厂类
public class ComputerFactory implements AbstractFactory {@Overridepublic Product createProduct() {return new Computer();}@Overridepublic Shipping createShipping() {return new ExpressShipping();}
}// 衣服工厂类
public class ClothesFactory implements AbstractFactory {@Overridepublic Product createProduct() {return new Clothes();}@Overridepublic Shipping createShipping() {return new PickupShipping();}
}

最后,在客户端代码中,我们可以使用具体的工厂类来创建相应的商品对象和物流对象:

public class Client {public static void main(String[] args) {AbstractFactory phoneFactory = new PhoneFactory();Product phone = phoneFactory.createProduct();Shipping phoneShipping = phoneFactory.createShipping();phone.showInfo();phoneShipping.ship();AbstractFactory computerFactory = new ComputerFactory();Product computer = computerFactory.createProduct();Shipping computerShipping = computerFactory.createShipping();computer.showInfo();computerShipping.ship();AbstractFactory clothesFactory = new ClothesFactory();Product clothes = clothesFactory.createProduct();Shipping clothesShipping = clothesFactory.createShipping();clothes.showInfo();clothesShipping.ship();}
}

运行Client类,输出结果为:

这是一部手机
使用快递进行运输
这是一台电脑
使用快递进行运输
这是一件衣服
自提,无需运输

通过抽象工厂模式,我们可以为每种商品类型创建一个对应的工厂类,而不是为每个商品类型和物流方式组合创建具体工厂类。这样一来,客户端只需要针对抽象工厂和产品接口编程,减少了直接依赖具体类的情况,提高了代码的灵活性和可扩展性。同时,抽象工厂模式也使得不同类型的产品之间可以进行组合,形成产品族,更加符合面向对象的设计原则。

在抽象工厂模式中,给每个产品额外添加了快递物流的方式。抽象工厂模式更适合于管理产品族,不同产品族有不同的工厂方法。

参考:
AI Chat 设计模式:2. 工厂设计模式

相关文章:

GPT带我学-设计模式-工厂模式

1 你好,请问你知道设计模式的工厂模式吗 当然知道,工厂模式是一种创建型设计模式,它提供了一种创建对象的方式,而不需要暴露对象创建的逻辑细节。工厂模式通过使用工厂类来创建对象,从而将对象的实例化逻辑与客户端代…...

Docker 安装 Tomcat

目录 一、查看 tomcat 版本 二、拉取 Tomcat Docker 镜像 三、创建 Tomcat 容器 四、访问 Tomcat 五、停止和启动容器 一、查看 tomcat 版本 访问 tomcat 镜像库地址:https://hub.docker.com/_/tomcat,可以通过 Tags 查看其他版本的 tomcat; 二、拉…...

seata注册到nacos(docker)

1、安装:docker run --name seata-server2 -p 8091:8091 -p 7091:7091 seataio/seata-server:1.5.1 复制seata-server2到服务器,然后过河拆桥 2、创建挂载目录 mkdir -p /ssy/seata_docker 3、将容器 resources文件挂载到宿主机 docker cp seata-server2…...

ffmpeg综合应用示例(五)——多路视频合并(Linux版本)

本文的目的为方便Linux下编译运行多路视频合成Demo 原文:ffmpeg综合应用示例(五)——多路视频合并 Ubuntu 20.04 ffmpeg version ffmpeg-4.4-x86_64 编译 export LD_LIBRARY_PATH$LD_LIBRARY_PATH:/home/workspace/dengzr/linux-x64/lib…...

Node.js-http模块服务端请求与响应操作,请求报文与响应报文

简单案例创建HTTP服务端: // 导入 http 模块 const http require("http"); // 创建服务对象 const server http.createServer((request, response) > {// 设置编码格式,解决中文乱码问题response.setHeader("content-type", &…...

除了PS,还有那些软件可以打开PSD文件

设计师在交接文件时,会看到各种格式的扩展文件,不同的格式需要不同的软件来运行。大多数人都听说过流行的文件格式PSD,因为它是最常用的图片格式之一,还有JPG、PNG等。然而,与JPG和PNG不同的是,PSD格式文件…...

uniapp h5支付宝支付后端返回Form表单,前端如何处理

提示:文章写完后,目录可以自动生成,如何生成可参考右边的帮助文档 文章目录 前言1.调取接口拿到后端返回的form表单 前言 uniapp h5 支付宝支付,后端返回一串form表单,前端如何拿到支付串并且调用支付 1.调取接口拿到…...

【华秋干货铺】PCB布线技巧升级:高速信号篇

如下表所示,接口信号能工作在8Gbps及以上速率,由于速率很高,PCB布线设计要求会更严格,在前几篇关于PCB布线内容的基础上,还需要根据本篇内容的要求来进行PCB布线设计。 高速信号布线时尽量少打孔换层,换层优…...

c#:ObservableCollection<T>的用法

1.说明: ObservableCollection:表示一个动态数据收集,该集合在添加或删除项或刷新整个列表时提供通知。 2.使用: 首先声明一个类 public ObservableCollection ProItems;//具体情况具体写对应的信息 表格DataGrid案例&#xff…...

Linux 端口号占用如何处理(使用命令处理)

查看被占用端口号 sudo netstat -tlnp 端口号 示例: sudo netstat -tlnp 3380杀死进程 sudo kill 进程Id sudo kill 11032...

ubuntu git操作记录设置ssh key

用到的命令: 安装git sudo apt-get install git配置git用户和邮箱 git config --global user.name “用户名” git config --global user.email “邮箱地址”安装ssh sudo apt-get install ssh然后查看安装状态: ps -e | grep sshd4. 查看有无ssh k…...

SystemVerilog数组参数传递及引用方法总结

一、将常数数组传递给task/function 如下面的程序,将一个常数数组传递给function module my_array_test();function array_test(int array[4]);foreach(array[i]) begin$display("array[%0d] %0d", i, array[i]);endendfunctioninitial beginarray_tes…...

Shell脚本学习-While循环1

当型循环和直到型循环: 循环语句常用于重复执行一条指令或一组指令,直到条件不满足时停止。 在企业实际应用中,常用于守护进程或者持续运行的程序。 while语法结构: while 条件 do指令... done while循环语句对后面的条件表达…...

docker for Windows, WSL2 ,Hyper-v的关系

Hyper-v Hyper-V是由微软开发的一种虚拟化技术和虚拟机管理器。它允许在Windows操作系统上创建和运行多个虚拟机实例,每个虚拟机可以运行独立的操作系统和应用程序。属于硬件虚拟化。 WSL2 WSL2在技术上与WSL有很大的不同。在WSL2中,Windows 10引入了…...

SAS-数据集SQL水平合并

一、SQL水平合并基本语法 sql的合并有两步,step1:进行笛卡尔乘积运算,第一个表的每一行合并第二个表的每一行,即表a有3行,表b有3行,则合并后3*39行。笛卡尔过程包含源数据的所有列,相同列名会合…...

企业既要用u盘又要防止u盘泄密怎么办?

企业在日常生产生活过程中,使用u盘交换数据是最企业最常用也是最便携的方式,但是在使用u盘的同时,也给企业的数据保密工作带来了很大的挑战,往往很多情况下企业的是通过u盘进行数据泄漏的。很多企业采用一刀切的方式,直…...

汉明距离,两个整数之间的 汉明距离 指的是这两个数字对应二进制位不同的位置的数目。

题记: 两个整数之间的 汉明距离 指的是这两个数字对应二进制位不同的位置的数目。 给你两个整数 x 和 y,计算并返回它们之间的汉明距离。 示例 1: 输入:x 1, y 4 输出:2 解释: 1 (0 0 0 1) 4 (0 1 0 0…...

Android 之 使用 Camera 拍照

本节引言 本节给大家带来的是Android中Camera的使用,简单点说就是拍照咯,无非两种: 1.调用系统自带相机拍照,然后获取拍照后的图片 2.要么自己写个拍照页面 本节我们来写两个简单的例子体验下上面的这两种情况~ 1.调用系统自带…...

盘点7月Sui生态发展,了解Sui的近期成长历程!

自5月Sui主网上线三个月以来,7月是Sui网络进行最多次重要更新的一个月,Sui网络和生态正呈指数形式不断向上发展。为吸引更多的项目或开发者加入生态构建以及活跃用户参与生态,Sui基金会推出了Builder House、黑客松、Bullshark Quests、NFT再…...

6.物联网操作系统信号量

一。信号量的概念与应用 信号量定义 FreeRTOS信号量介绍 FreeRTOS信号量工作原理 1.信号量的定义 多任务环境下使用,用来协调多个任务正确合理使用临界资源。 2.FreeRTOS信号量介绍 Semaphore包括Binary,Count,Mutex; Mutex包…...

鸿蒙系统微博应用锁常见问题解答

为微博设置应用锁后,不少用户会有各种疑问:忘记密码怎么办?会不会影响消息推送?能不能只锁定某些功能?应用锁耗电吗?本文将针对这些高频问题逐一解答,帮助您更好地使用鸿蒙系统(Harm…...

嘈杂工业场景下的自适应VAD与双码本声纹识别鉴权系统:基于端侧轻量化神经网络与向量量化(VQ)重构

在大型化工车间、能源集控中心以及金融极密隔离库房中,离线声纹识别是物理访问控制和身份安全核验的重要生物特征屏障。然而,在环境本底噪声高达80dB以上的恶劣工业场景下,常规的语音活动检测(VAD)会频繁误触&#xff…...

WebSocket实时通信架构进阶:Room、命名空间与集群部署

WebSocket实时通信架构进阶:Room、命名空间与集群部署 作者:Crown_22 | AI Agent & Hermes Agent 桌面程序开发者 前言 WebSocket已经成为实时应用的标准技术,但大多数教程只停留在"建立连接、发送消息"的基础阶段。在生产环境中,你需要处理Room管理、命名空…...

YOLOv8晶圆体缺识别检测系统(项目源码+YOLO数据集+模型权重+UI界面+python+深度学习+环境配置)

摘要 晶圆制造过程中的缺陷检测是保证芯片良率的关键环节。本文基于YOLOv8目标检测算法,构建了一套针对晶圆表面9类典型缺陷的自动检测系统。所识别的缺陷类型包括:Center、Donut、Edge-Loc、Edge-Ring、Loc、Near-full、None、Random、Scratch。模型在…...

解决方法:庐山派K230接串口没识别到端口问题

一、插入usb转串口工具之前二、插入usb转串口工具之后三、解决方法说明:🔍 核心原因:USB Serial 设备,没有被识别为 COM 口你现在看到的 USB Serial,说明开发板已经正常启动了,USB 也被电脑识别到了&#x…...

BetterNCM安装器终极指南:5分钟解锁网易云音乐无限潜能

BetterNCM安装器终极指南:5分钟解锁网易云音乐无限潜能 【免费下载链接】BetterNCM-Installer 一键安装 Better 系软件 项目地址: https://gitcode.com/gh_mirrors/be/BetterNCM-Installer 你是否觉得网易云音乐PC版功能有限,界面单调&#xff1f…...

使用libusb-win32驱动复活老旧USB硬件:以Elektor Magic Eye为例

1. 项目概述:让老硬件在新时代焕发新生手头有一台十多年前的《Elektor》杂志上刊登的“Magic Eye EM84”复古VFD显示屏项目,想把它接到Windows 10电脑上当个酷炫的CPU占用率显示器,却发现官方提供的“AVR309”USB驱动在新系统上彻底罢工了。这…...

Awoo Installer:让Switch游戏安装变得简单高效的终极解决方案

Awoo Installer:让Switch游戏安装变得简单高效的终极解决方案 【免费下载链接】Awoo-Installer A No-Bullshit NSP, NSZ, XCI, and XCZ Installer for Nintendo Switch 项目地址: https://gitcode.com/gh_mirrors/aw/Awoo-Installer 厌倦了繁琐的Switch游戏安…...

为什么92%的数据库重构失败?Claude设计辅助如何在48小时内规避反范式陷阱?

更多请点击: https://codechina.net 第一章:为什么92%的数据库重构失败?——反范式陷阱的本质溯源 数据库重构失败率高达92%,其核心症结并非技术能力不足,而是对“反范式”这一设计策略的误读与滥用。许多团队在性能压…...

PDF差异对比神器diff-pdf:告别文档核对烦恼,提升工作效率的智能解决方案

PDF差异对比神器diff-pdf:告别文档核对烦恼,提升工作效率的智能解决方案 【免费下载链接】diff-pdf A simple tool for visually comparing two PDF files 项目地址: https://gitcode.com/gh_mirrors/di/diff-pdf 你是否曾在核对PDF文档时感到头疼…...