Java设计模式-工厂模式
目录
一、简单工厂模式
(一)需求
(二)使用传统的方法来完成
(三)传统方法的优缺点
(四)基本介绍
(五)使用简单工厂模式
二、工厂方法模式
(一)需求
(二)思路
(三)基本介绍
(四)工厂方法模式应用
三、抽象工厂模式
(一)基本介绍
(二)应用实例
一、简单工厂模式
(一)需求
- 披萨的种类很多(比如 GreekPizz、CheesePizz 等)
- 披萨的制作有 prepare,bake, cut, box
- 完成披萨店订购功能。
(二)使用传统的方法来完成
1、类图
2、代码
pizza类
//将Pizza 类做成抽象
public abstract class Pizza {protected String name; //名字//准备原材料, 不同的披萨不一样,因此,我们做成抽象方法public abstract void prepare();public void bake() {System.out.println(name + " baking;");}public void cut() {System.out.println(name + " cutting;");}//打包public void box() {System.out.println(name + " boxing;");}public void setName(String name) {this.name = name;}
}
两种pizza
public class GreekPizza extends Pizza {@Overridepublic void prepare() {// TODO Auto-generated method stubSystem.out.println(" 给希腊披萨 准备原材料 ");}}=========================================================
public class CheesePizza extends Pizza {@Overridepublic void prepare() {// TODO Auto-generated method stubSystem.out.println(" 给制作奶酪披萨 准备原材料 ");}
}
编写OrderPizza去订购需要的各种pizza
public class OrderPizza {// 构造器public OrderPizza() {Pizza pizza = null;String orderType; // 订购披萨的类型do {orderType = getType();if (orderType.equals("greek")) {pizza = new GreekPizza();pizza.setName(" 希腊披萨 ");} else if (orderType.equals("cheese")) {pizza = new CheesePizza();pizza.setName(" 奶酪披萨 ");} else if (orderType.equals("pepper")) {pizza = new PepperPizza();pizza.setName("胡椒披萨");} else {break;}//输出pizza 制作过程pizza.prepare();pizza.bake();pizza.cut();pizza.box();} while (true);}
}
客户端订购pizza
//相当于一个客户端,发出订购
public class PizzaStore {public static void main(String[] args) {// TODO Auto-generated method stubnew OrderPizza();}}
(三)传统方法的优缺点
(四)基本介绍
- 简单工厂模式是属于创建型模式,是工厂模式的一种。简单工厂模式是由一个工厂对象决定创建出哪一种产品类的实例。简单工厂模式是工厂模式家族中最简单实用的模式
- 简单工厂模式:定义了一个创建对象的类,由这个类来封装实例化对象的行为(代码)
- 在软件开发中,当我们会用到大量的创建某种、某类或者某批对象时,就会使用到工厂模式
在简单工厂模式中,主要涉及三个角色:抽象产品、具体产品和简单工厂。
抽象产品:抽象产品可以是一个接口或抽象类,定义了产品通用的方法,有具体子类来实现
具体产品:具体产品是抽象产品的实现类,它实现了抽象产品中定义的方法
简单工厂:包含创建对象的方法,隐藏了创建对象细节。
(五)使用简单工厂模式
将对象的创建逻辑封装在一个工厂类中,客户端不需要知道具体的创建细节,只需要向工厂类请求所需对象即可。
简单工厂类,封装了创建对象的方法
//简单工厂类,封装了创建对象的细节
public class SimpleFactory {//根据orderType 返回对应的Pizza 对象public Pizza createPizza(String orderType) {Pizza pizza = null;System.out.println("使用简单工厂模式");if (orderType.equals("greek")) {pizza = new GreekPizza();pizza.setName(" 希腊披萨 ");} else if (orderType.equals("cheese")) {pizza = new CheesePizza();pizza.setName(" 奶酪披萨 ");} else if (orderType.equals("pepper")) {pizza = new PepperPizza();pizza.setName("胡椒披萨");}return pizza;}}
orderpizza
public class OrderPizza {//定义一个简单工厂对象SimpleFactory simpleFactory;Pizza pizza = null;//构造器public OrderPizza(SimpleFactory simpleFactory) {setFactory(simpleFactory);}public void setFactory(SimpleFactory simpleFactory) {String orderType = ""; //用户输入的this.simpleFactory = simpleFactory; //设置简单工厂对象do {orderType = getType(); pizza = this.simpleFactory.createPizza(orderType);//输出pizzaif(pizza != null) { //订购成功pizza.prepare();pizza.bake();pizza.cut();pizza.box();} else {System.out.println(" 订购披萨失败 ");break;}}while(true);}// 写一个方法,可以获取客户希望订购的披萨种类private String getType() {try {BufferedReader strin = new BufferedReader(new InputStreamReader(System.in));System.out.println("input pizza 种类:");String str = strin.readLine();return str;} catch (IOException e) {e.printStackTrace();return "";}}}
客户端下单
//相当于一个客户端,发出订购
public class PizzaStore {public static void main(String[] args) {//使用简单工厂模式new OrderPizza(new SimpleFactory());System.out.println("~~退出程序~~");}}
其实工厂模式还叫静态工厂模式,也就是把创建对象的方法设置为静态方法,那就不需要创建工厂对象了,直接用类名的方式调用工厂创建对象的方法即可。
//简单工厂类,封装了创建对象的细节
public class SimpleFactory {//简单工厂模式 也叫 静态工厂模式public static Pizza createPizza(String orderType) {Pizza pizza = null;System.out.println("使用简单工厂模式2");if (orderType.equals("greek")) {pizza = new GreekPizza();pizza.setName(" 希腊披萨 ");} else if (orderType.equals("cheese")) {pizza = new CheesePizza();pizza.setName(" 奶酪披萨 ");} else if (orderType.equals("pepper")) {pizza = new PepperPizza();pizza.setName("胡椒披萨");}return pizza;}}
orderpizza
public class OrderPizza2 {Pizza pizza = null;String orderType = "";// 构造器public OrderPizza2() {do {orderType = getType();pizza = SimpleFactory.createPizza2(orderType);// 输出pizzaif (pizza != null) { // 订购成功pizza.prepare();pizza.bake();pizza.cut();pizza.box();} else {System.out.println(" 订购披萨失败 ");break;}} while (true);}// 写一个方法,可以获取客户希望订购的披萨种类private String getType() {try {BufferedReader strin = new BufferedReader(new InputStreamReader(System.in));System.out.println("input pizza 种类:");String str = strin.readLine();return str;} catch (IOException e) {e.printStackTrace();return "";}}
}
总结:工厂封装了对象的创建过程,降低了客户端的复杂性,并且方便了产品类型的扩展和维护。
二、工厂方法模式
(一)需求
(二)思路
思路1

(三)基本介绍
在工厂方法模式中,主要涉及三个角色:抽象产品、具体产品、简单工厂和具体工厂
抽象产品:抽象产品可以是一个接口或抽象类,定义了产品通用的方法,由具体子类来实现
具体产品:具体产品是抽象产品的实现类,它实现了抽象产品中定义的方法
抽象工厂:定义了创建产品的接口,包含一个或多个创建产品的抽象方法。
具体工厂:实现了抽象工厂接口,负责实例化具体产品。
(四)工厂方法模式应用
//将Pizza 类做成抽象
public abstract class Pizza {protected String name; //名字//准备原材料, 不同的披萨不一样,因此,我们做成抽象方法public abstract void prepare();public void bake() {System.out.println(name + " baking;");}public void cut() {System.out.println(name + " cutting;");}//打包public void box() {System.out.println(name + " boxing;");}public void setName(String name) {this.name = name;}
}
各种pizza
public class LDPepperPizza extends Pizza{@Overridepublic void prepare() {// TODO Auto-generated method stubsetName("伦敦的胡椒pizza");System.out.println(" 伦敦的胡椒pizza 准备原材料");}
}==============================================
public class LDCheesePizza extends Pizza{@Overridepublic void prepare() {// TODO Auto-generated method stubsetName("伦敦的奶酪pizza");System.out.println(" 伦敦的奶酪pizza 准备原材料");}
}==============================================
public class BJPepperPizza extends Pizza {@Overridepublic void prepare() {// TODO Auto-generated method stubsetName("北京的胡椒pizza");System.out.println(" 北京的胡椒pizza 准备原材料");}
}==============================================
public class BJCheesePizza extends Pizza {@Overridepublic void prepare() {// TODO Auto-generated method stubsetName("北京的奶酪pizza");System.out.println(" 北京的奶酪pizza 准备原材料");}}
orderpizza
public abstract class OrderPizza {//定义一个抽象方法,createPizza , 让各个工厂子类自己实现abstract Pizza createPizza(String orderType);// 构造器public OrderPizza() {Pizza pizza = null;String orderType; // 订购披萨的类型do {orderType = getType();pizza = createPizza(orderType); //抽象方法,由工厂子类完成//输出pizza 制作过程pizza.prepare();pizza.bake();pizza.cut();pizza.box();} while (true);}// 写一个方法,可以获取客户希望订购的披萨种类private String getType() {try {BufferedReader strin = new BufferedReader(new InputStreamReader(System.in));System.out.println("input pizza 种类:");String str = strin.readLine();return str;} catch (IOException e) {e.printStackTrace();return "";}}
}
public class LDOrderPizza extends OrderPizza {@OverridePizza createPizza(String orderType) {Pizza pizza = null;if(orderType.equals("cheese")) {pizza = new LDCheesePizza();} else if (orderType.equals("pepper")) {pizza = new LDPepperPizza();}// TODO Auto-generated method stubreturn pizza;}}==============================================
public class BJOrderPizza extends OrderPizza {@OverridePizza createPizza(String orderType) {Pizza pizza = null;if(orderType.equals("cheese")) {pizza = new BJCheesePizza();} else if (orderType.equals("pepper")) {pizza = new BJPepperPizza();}// TODO Auto-generated method stubreturn pizza;}}
PizzaStore
public class PizzaStore {public static void main(String[] args) {String loc = "bj";if (loc.equals("bj")) {//创建北京口味的各种Pizzanew BJOrderPizza();} else {//创建伦敦口味的各种Pizzanew LDOrderPizza();}// TODO Auto-generated method stub}}
总结:当需要新增pizza类型时,只需要实现具体的产品和具体的工厂即可,而无需修改客户端的代码。
三、抽象工厂模式
(一)基本介绍
- 抽象工厂模式:定义了一个interface用于创建相关或有依赖关系的对象簇,而无需指明具体的类
- 抽象工厂模式可以将简单工厂模式和工厂方法模式进行整合。
- 从设计层面看,抽象工厂模式就是对简单工厂模式的改进(或者称为进一步的抽象)。
- 将工厂抽象成两层,AbsFactory(抽象工厂) 和 具体实现的工厂子类。程序员可以根据创建对象类型使用对应的工厂子类。这样将单个的简单工厂类变成了工厂簇,更利于代码的维护和扩展。
类图如下:
(二)应用实例
抽象工厂
//一个抽象工厂模式的抽象层(接口)
public interface AbsFactory {//让下面的工厂子类来 具体实现public Pizza createPizza(String orderType);
}
工厂实现类
//这是工厂子类
public class BJFactory implements AbsFactory {@Overridepublic Pizza createPizza(String orderType) {System.out.println("~使用的是抽象工厂模式~");// TODO Auto-generated method stubPizza pizza = null;if(orderType.equals("cheese")) {pizza = new BJCheesePizza();} else if (orderType.equals("pepper")){pizza = new BJPepperPizza();}return pizza;}}==================================================
public class LDFactory implements AbsFactory {@Overridepublic Pizza createPizza(String orderType) {System.out.println("~使用的是抽象工厂模式~");Pizza pizza = null;if (orderType.equals("cheese")) {pizza = new LDCheesePizza();} else if (orderType.equals("pepper")) {pizza = new LDPepperPizza();}return pizza;}}
订购披萨的类,通过聚合的方式设置工厂
public class OrderPizza {AbsFactory factory;// 构造器public OrderPizza(AbsFactory factory) {setFactory(factory);}private void setFactory(AbsFactory factory) {Pizza pizza = null;String orderType = ""; // 用户输入this.factory = factory;do {orderType = getType();// factory 可能是北京的工厂子类,也可能是伦敦的工厂子类pizza = factory.createPizza(orderType);if (pizza != null) { // 订购okpizza.prepare();pizza.bake();pizza.cut();pizza.box();} else {System.out.println("订购失败");break;}} while (true);}// 写一个方法,可以获取客户希望订购的披萨种类private String getType() {try {BufferedReader strin = new BufferedReader(new InputStreamReader(System.in));System.out.println("input pizza 种类:");String str = strin.readLine();return str;} catch (IOException e) {e.printStackTrace();return "";}}
}
相关文章:

Java设计模式-工厂模式
目录 一、简单工厂模式 (一)需求 (二)使用传统的方法来完成 (三)传统方法的优缺点 (四)基本介绍 (五)使用简单工厂模式 二、工厂方法模式 ࿰…...

每天五分钟计算机视觉:稠密连接网络(DenseNet)
本文重点 在前面的课程中我们学习了残差网络ResNet,而DenseNet可以看成是ResNet的后续,我们看一下图就可以看出二者的主要区别了。 特点 DenseNet是一种卷积神经网络,它的特点是每一层都直接连接到所有后续层。这意味着,每一层都接收来自前一层的输出,并将其作为输入传递…...
mysql支持的整数类型、各类型整数能够表示的数值范围
MySQL :: MySQL 8.2 Reference Manual :: 11.1.2 Integer Types (Exact Value) - INTEGER, INT, SMALLINT, TINYINT, MEDIUMINT, BIGINT mysql支持的整数有:TINYINT、SMALLINT、MEDIUMINT、INT(INT和INTEGER是同义词)、BIGINT,各…...

我不是DBA之慢SQL诊断方式
最近经常遇到技术开发跑来问我慢SQL优化相关工作,所以干脆出几篇SQL相关优化技术月报,我这里就以公司mysql一致的5.7版本来说明下。 在企业中慢SQL问题进场会遇到,尤其像我们这种ERP行业。 成熟的公司企业都会有晚上的慢SQL监控和预警机制。…...

JavaScript基础知识整理(最全知识点, 精简版,0基础版)
文章目录 一、输入和输出内容 1.1 输出 1.1.1 在浏览器的控制台输出打印 1.1.2 直接在浏览器的页面上输出内容 1.1.3 页面弹出警告对话框 1.2 输入 二、变量 2.1 变量是什么 2.2 变量的声明和赋值 2.3 变量的命名规范和规范 三、变量扩展(数组) 3.1 数组…...

人工智能和网络安全:坏与好
人工智能似乎可以并且已经被用来帮助网络犯罪和网络攻击的各个方面。 人工智能可以用来令人信服地模仿真人的声音。人工智能工具可以帮助诈骗者制作更好、语法正确的网络钓鱼消息(而糟糕的语法往往会暴露出漏洞),并将其翻译成多种语言&…...

基于SSH的java记账管理系统
基于SSH的java记账管理系统 一、系统介绍二、功能展示四、其他系统实现五、获取源码 一、系统介绍 项目类型:Java EE项目 项目名称:基于SSH的记账管理系统 项目架构:B/S架构 开发语言:Java语言 前端技术:HTML、CS…...
github可访问但无法clone问题
github可访问但无法clone问题 重置 http.proxy 重置 http.proxy git config --global http.proxy http://127.0.0.1:1080 git config --global https.proxy https://127.0.0.1:1080 git config --global --unset http.proxy git config --global --unset https.proxy...

WebGL笔记:图形缩放的原理和实现
缩放 1 )原理 缩放可以理解为对向量长度的改变,或者对向量坐标分量的同步缩放 如下图,比如让向量OA 收缩到点B的位置,也就是从OA变成OB,缩放了一半 2 )公式 已知 点A的位置是(ax,ay,az)点A基于原点內缩了…...
前端学习--React(5)
一、useReducer 管理相对复杂的状态数据 定义一个reducer函数,根据action值的不同返回不同的状态 在组件中调用useReducer并传入reducer函数和状态的初始值 事件发生时,通过dispatch函数分派一个对象,即通知reducer具体返回哪个状态对应的操…...

【数据结构】平衡树引入
数据结构-平衡树 前置知识 二叉树二叉树的中序遍历 问题 维护一个数据结构,支持插入元素、删除元素、查询元素的排名、查询排名对应的元素、查询元素的前驱、查询元素的后继等。 BST(二叉搜索树) 作为一个基本无效(很容易卡掉…...

机器视觉相机镜头光源选型
镜头选型工具 - HiTools - 海康威视 Hikvisionhttps://www.hikvision.com/cn/support/tools/hitools/cl8a9de13648c56d7f/ 海康机器人-机器视觉产品页杭州海康机器人股份有限公司海康机器人HIKROBOT是面向全球的机器视觉和移动机器人产品及解决方案提供商,业务聚焦于…...
Appium:iOS测试比Android测试更难?
iOS测试与Android测试: Appium 是一个开源的自动化测试框架,用于iOS、Android和Web应用程序。它允许开发者使用自己的语言来编写测试脚本,并且可以运行在多种平台上。 就Appium本身而言,它为iOS和Android提供了相似的测试能力和…...
使用c#罗列、监视、控制进程
个人简介:本人多年从事研发和测试领域工作,有一定的经验; 口号:懒人推动科技进步,学习编程啊脚本啊目的就是要将人从做相同的工作脱离出来,手懒可以但是脑子不能懒,让重复的事情自动完成,能动一下就完成任务就不能动两下,懒到极致才是目标! 方向:本人不怎么将理论的…...

Vue:绘制图例
本文记录使用Vue框架绘制图例的代码片段。 可以嵌入到cesium视图中,也可以直接绘制到自己的原生系统中。 一、绘制图例Vue组件 <div v-for="(color, index) in colors" :key="index" class="legend-item"><div class="color-…...

Web(8)SQL注入
Web网站(对外门户) 原理:not>and>or(优先级) 一.低级注入 order by的作用是对字段进行排序,如order by 5,根据第五个字段 进行排序,如果一共有4个字段,输入order by 5系统就会报错不 …...
kafka入门(三):kafka多线程消费
kafka消费积压 如果生产者发送消息的速度过快,或者是消费者处理消息的速度太慢,那么就会有越来越多的消息无法及时消费,也就是消费积压。 消费积压时, (1) 可以增加Topic的分区数,并且增加消费组的消费者数量&#…...
android通过广播打印RAM信息
通过广播打印ram相关log 参数说明: 广播:com.android.settings.action.RAM_INFO int型参数index:0 - 3h, 1 - 6h, 2 - 12h, 3 - 24h 代表过去时间app使用ram情况(平均/最大占用) Index: frameworks/base/services/cor…...

C++新经典模板与泛型编程:策略类模板
策略类模板 在前面的博文中,策略类SumPolicy和MinPolicy都是普通的类,其中包含的是一个静态成员函数模板algorithm(),该函数模板包含两个类型模板参数。其实,也可以把SumPolicy和MinPolicy类写成类模板—直接把algorithm()中的两…...

微信小程序引入Vant Weapp修改样式不起作用,使用外部样式类进行覆盖
一、引入Vant Weapp后样式问题 在项目中使用第三方组件修改css样式时,总是出现各种各样问题,修改的css样式不起作用,没有效果,效果不符合预期等。 栗子(引入一个搜索框组件)实现效果: 左侧有一个搜索文字背景为蓝色,接着跟一个搜索框 wxml <view class"container&q…...

【大模型RAG】拍照搜题技术架构速览:三层管道、两级检索、兜底大模型
摘要 拍照搜题系统采用“三层管道(多模态 OCR → 语义检索 → 答案渲染)、两级检索(倒排 BM25 向量 HNSW)并以大语言模型兜底”的整体框架: 多模态 OCR 层 将题目图片经过超分、去噪、倾斜校正后,分别用…...
在 Nginx Stream 层“改写”MQTT ngx_stream_mqtt_filter_module
1、为什么要修改 CONNECT 报文? 多租户隔离:自动为接入设备追加租户前缀,后端按 ClientID 拆分队列。零代码鉴权:将入站用户名替换为 OAuth Access-Token,后端 Broker 统一校验。灰度发布:根据 IP/地理位写…...

江苏艾立泰跨国资源接力:废料变黄金的绿色供应链革命
在华东塑料包装行业面临限塑令深度调整的背景下,江苏艾立泰以一场跨国资源接力的创新实践,重新定义了绿色供应链的边界。 跨国回收网络:废料变黄金的全球棋局 艾立泰在欧洲、东南亚建立再生塑料回收点,将海外废弃包装箱通过标准…...
使用van-uploader 的UI组件,结合vue2如何实现图片上传组件的封装
以下是基于 vant-ui(适配 Vue2 版本 )实现截图中照片上传预览、删除功能,并封装成可复用组件的完整代码,包含样式和逻辑实现,可直接在 Vue2 项目中使用: 1. 封装的图片上传组件 ImageUploader.vue <te…...

视频字幕质量评估的大规模细粒度基准
大家读完觉得有帮助记得关注和点赞!!! 摘要 视频字幕在文本到视频生成任务中起着至关重要的作用,因为它们的质量直接影响所生成视频的语义连贯性和视觉保真度。尽管大型视觉-语言模型(VLMs)在字幕生成方面…...

【单片机期末】单片机系统设计
主要内容:系统状态机,系统时基,系统需求分析,系统构建,系统状态流图 一、题目要求 二、绘制系统状态流图 题目:根据上述描述绘制系统状态流图,注明状态转移条件及方向。 三、利用定时器产生时…...
爬虫基础学习day2
# 爬虫设计领域 工商:企查查、天眼查短视频:抖音、快手、西瓜 ---> 飞瓜电商:京东、淘宝、聚美优品、亚马逊 ---> 分析店铺经营决策标题、排名航空:抓取所有航空公司价格 ---> 去哪儿自媒体:采集自媒体数据进…...
今日学习:Spring线程池|并发修改异常|链路丢失|登录续期|VIP过期策略|数值类缓存
文章目录 优雅版线程池ThreadPoolTaskExecutor和ThreadPoolTaskExecutor的装饰器并发修改异常并发修改异常简介实现机制设计原因及意义 使用线程池造成的链路丢失问题线程池导致的链路丢失问题发生原因 常见解决方法更好的解决方法设计精妙之处 登录续期登录续期常见实现方式特…...

Razor编程中@Html的方法使用大全
文章目录 1. 基础HTML辅助方法1.1 Html.ActionLink()1.2 Html.RouteLink()1.3 Html.Display() / Html.DisplayFor()1.4 Html.Editor() / Html.EditorFor()1.5 Html.Label() / Html.LabelFor()1.6 Html.TextBox() / Html.TextBoxFor() 2. 表单相关辅助方法2.1 Html.BeginForm() …...
关于uniapp展示PDF的解决方案
在 UniApp 的 H5 环境中使用 pdf-vue3 组件可以实现完整的 PDF 预览功能。以下是详细实现步骤和注意事项: 一、安装依赖 安装 pdf-vue3 和 PDF.js 核心库: npm install pdf-vue3 pdfjs-dist二、基本使用示例 <template><view class"con…...