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. 工厂设计模式

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

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

相关文章

Json文件编辑功能

1 Json格式 JSON(JavaScript Object Notation) 是一种轻量级的数据交换格式。它基于 ECMAScript(European Computer Manufacturers Association, 欧洲计算机协会制定的js规范)的一个子集,采用完全独立于编程语言的文本格式来存储和表示数据。…

Maven引入本地jar包

maven做为一种强大的依赖管理工具,可以帮助我们更方便的管理项目中的依赖;而在使用过程中我们难免会有需要引入本地jar包的需求,这里踩过坑之后我分享俩种引入方式; 1.上传jar到本地maven仓库,再引入 使用此方法后可…

echarts datazoom功能设置

dataZoom: [ {type: slider,handleSize: "0%",moveHandleSize: 0,height: 8,backgroundColor: "#F2F3F8",fillerColor: "#DCDFE6",bottom: 0,startValue: 0,endValue: 5,showDetail: false ,zoomLock: true,// 锁定窗口的大小filterMode:empty,m…

CAD产品设计逆向软件 FARO RevEng Crack

CAD产品设计逆向软件 FARO RevEng 软件平台能为用户带来全面的数字设计体验。该反向工程软件有助于利用三维点云创建和编辑高质量的网格和 CAD 表面,以实现反向工程工作流程。然后,工业设计师可以利用这些网格模型进行进一步设计或三维打印。 RevEng 的商…

leetcode 983. 最低票价

在一个火车旅行很受欢迎的国度,你提前一年计划了一些火车旅行。在接下来的一年里,你要旅行的日子将以一个名为 days 的数组给出。每一项是一个从 1 到 365 的整数。 火车票有 三种不同的销售方式 : 一张 为期一天 的通行证售价为 costs[0] …

Java异常处理及spring boot异常统一处理

程序代码在没有问题的情况下是可以按照预定的业务逻辑正常的运行,并输出预定的结果;程序因为某些入参或程序未覆盖的逻辑以及一些资源限制等等导致程序不能按照预定逻辑正常执行,出现程序中断的情况就是异常。而针对异常往往需要修改代码避免…

【iOS RunLoop】

文章目录 前言-什么是RunLoop?默认情况下主线程的RunLoop原理 1. RunLoop对象RunLoop对象的获取 CFRunLoopRef源码部分(引入线程相关) 2. RunLoop和线程3. RunLoop相关的类RunLoop相关类的实现CFRunLoopModeRef五种运行模式CommonModes CFRun…

【MMCV】mmpretrain/mmclassification概览、环境安装与验证

概览 MMPretrain 是一个全新升级的预训练开源算法框架,旨在提供各种强大的预训练主干网络, 并支持了不同的预训练策略。MMPretrain 源自著名的开源项目 MMClassification 和 MMSelfSup,并开发了许多令人兴奋的新功能。 目前,预训练阶段对于视觉识别至关重要,凭借丰富而强…

MySQL - 9、存储过程和函数

创建存储过程、修改存储过程、删除存储过程、创建函数、修改函数、删除函数,以及调用存储过程和函数的操作: -- 创建存储过程 DELIMITER // CREATE PROCEDURE sp_example_procedure() BEGIN-- 存储过程的具体逻辑SELECT * FROM employees; END // DELIM…

C高级--day2(用户相关操作 磁盘相关操作 shell脚本 修改环境变量)

#include<myhead.h>void fun(int n) {if(n>9){fun(n/10);printf("%d\t",n%10);putchar(10);return;}else{printf("%d\n",n%10);return;} } int main(int argc, const char *argv[]) {int num;printf("请输入一个整数&#xff1a;");sca…

Maven引入本地第三方Jar包

背景 引入第三方的Jar包&#xff0c;本来是在项目结构的库里面引入的jar包&#xff0c;但是用maven打包时报错&#xff0c;所以后面想着用maven引入本地地址的方式。 解决方法 1.将Jar包放到根目录里面&#xff0c;我这边放在了lib文件中,如图所示&#xff1a; 2.在pom文件…

Mybatis引出的一系列问题-Mybatis缓存机制的探究

Mybatis 使用到了两种缓存&#xff1a;本地缓存&#xff08;local cache&#xff09;和二级缓存&#xff08;second level cache&#xff09;。 一级缓存默认是开启的&#xff0c;而且不能关闭&#xff0c;MyBatis的一些关键特性&#xff08;例如通过<association>和<…

机器人“瓦力”近在咫尺?谷歌最新的RT-2 AI模型简介

“首创”的机器人 AI 模型能够识别垃圾并执行复杂的动作。 上周五&#xff0c;谷歌 DeepMind 宣布了机器人变形器 2&#xff08;RT-2&#xff09;&#xff0c;这是一种“首次推出”的视觉-语言-行动&#xff08;VLA&#xff09;模型&#xff0c;利用从互联网上抓取的数据&…

Linux学习之延时计划任务anacontab和锁文件flock

cat /etc/redhat-release看到操作系统的版本是CentOS Linux release 7.6.1810 (Core)&#xff0c;uname -r可以看到内核版本是3.10.0-957.21.3.el7.x86_64 参考的博客有&#xff1a; 1.《Linux anacron命令用法详解》 2.《详解anacron 命令》 3.《Anacron的用法》 4.《shell脚…

C#的yield

在 C# 中&#xff0c;yield 关键字用于定义迭代器方法&#xff08;Iterator Methods&#xff09;&#xff0c;并使其返回一个可枚举的序列。通过使用 yield 关键字&#xff0c;可以简化迭代器的实现&#xff0c;使其更加直观和易于理解。 使用 yield 关键字定义的方法被称为迭…

Libevent开源库的介绍与应用

libeventhttps://libevent.org/ 一、初识 1、libevent介绍 Libevent 是一个用C语言编写的、轻量级的开源高性能事件通知库&#xff0c;主要有以下几个亮点&#xff1a;事件驱动&#xff08; event-driven&#xff09;&#xff0c;高性能;轻量级&#xff0c;专注于网络&#xff…

【雕爷学编程】MicroPython动手做(37)——驱动LCD与图文显示

MixPY——让爱(AI)触手可及 MixPY布局 主控芯片&#xff1a;K210&#xff08;64位双核带硬件FPU和卷积加速器的 RISC-V CPU&#xff09; 显示屏&#xff1a;LCD_2.8寸 320*240分辨率&#xff0c;支持电阻触摸 摄像头&#xff1a;OV2640&#xff0c;200W像素 扬声器&#…

【Ajax】笔记-设置CORS响应头实现跨域

CORS CORS CORS是什么&#xff1f; CORS(Cross-Origin Resource Sharing),跨域资源共享。CORS是官方的跨域解决方案&#xff0c;它的特点是不需要在客户端做任何特殊的操作&#xff0c;完全在服务器中进行处理&#xff0c;支持get和post请求。跨域资源共享标准新增了一组HTTP首…

页面技术基础-html

页面技术基础-html 环境准备&#xff1a;在JDBC中项目上完成代码定义 1. 新建一个 Module:filr->右键 -》Module -》Java-》next->名字(html_day1)->finish 2. 在 Moudle上右键-》第二个选项&#xff1a;add framework .. -> 选择JavaEE下第一个选项 Web Apllicat…

Vue系列第六篇:axios封装,登录逻辑优化,404页面实现,Go语言跨域处理

第五篇利用vue实现了登录页面&#xff0c;用go语言开发了服务端并最后在nginx上进行了部署。本篇将axios封装&#xff0c;登录逻辑优化&#xff0c;404页面实现。 目录 1.前端 1.1代码结构 1.2源码 2.服务端 2.1源码 3.运行效果 4.注意事项 4.1webpack.config.js和vue…