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…...
基于算法竞赛的c++编程(28)结构体的进阶应用
结构体的嵌套与复杂数据组织 在C中,结构体可以嵌套使用,形成更复杂的数据结构。例如,可以通过嵌套结构体描述多层级数据关系: struct Address {string city;string street;int zipCode; };struct Employee {string name;int id;…...
Vim 调用外部命令学习笔记
Vim 外部命令集成完全指南 文章目录 Vim 外部命令集成完全指南核心概念理解命令语法解析语法对比 常用外部命令详解文本排序与去重文本筛选与搜索高级 grep 搜索技巧文本替换与编辑字符处理高级文本处理编程语言处理其他实用命令 范围操作示例指定行范围处理复合命令示例 实用技…...
第19节 Node.js Express 框架
Express 是一个为Node.js设计的web开发框架,它基于nodejs平台。 Express 简介 Express是一个简洁而灵活的node.js Web应用框架, 提供了一系列强大特性帮助你创建各种Web应用,和丰富的HTTP工具。 使用Express可以快速地搭建一个完整功能的网站。 Expre…...
Admin.Net中的消息通信SignalR解释
定义集线器接口 IOnlineUserHub public interface IOnlineUserHub {/// 在线用户列表Task OnlineUserList(OnlineUserList context);/// 强制下线Task ForceOffline(object context);/// 发布站内消息Task PublicNotice(SysNotice context);/// 接收消息Task ReceiveMessage(…...
通过Wrangler CLI在worker中创建数据库和表
官方使用文档:Getting started Cloudflare D1 docs 创建数据库 在命令行中执行完成之后,会在本地和远程创建数据库: npx wranglerlatest d1 create prod-d1-tutorial 在cf中就可以看到数据库: 现在,您的Cloudfla…...
Nginx server_name 配置说明
Nginx 是一个高性能的反向代理和负载均衡服务器,其核心配置之一是 server 块中的 server_name 指令。server_name 决定了 Nginx 如何根据客户端请求的 Host 头匹配对应的虚拟主机(Virtual Host)。 1. 简介 Nginx 使用 server_name 指令来确定…...
【单片机期末】单片机系统设计
主要内容:系统状态机,系统时基,系统需求分析,系统构建,系统状态流图 一、题目要求 二、绘制系统状态流图 题目:根据上述描述绘制系统状态流图,注明状态转移条件及方向。 三、利用定时器产生时…...
全面解析各类VPN技术:GRE、IPsec、L2TP、SSL与MPLS VPN对比
目录 引言 VPN技术概述 GRE VPN 3.1 GRE封装结构 3.2 GRE的应用场景 GRE over IPsec 4.1 GRE over IPsec封装结构 4.2 为什么使用GRE over IPsec? IPsec VPN 5.1 IPsec传输模式(Transport Mode) 5.2 IPsec隧道模式(Tunne…...
【数据分析】R版IntelliGenes用于生物标志物发现的可解释机器学习
禁止商业或二改转载,仅供自学使用,侵权必究,如需截取部分内容请后台联系作者! 文章目录 介绍流程步骤1. 输入数据2. 特征选择3. 模型训练4. I-Genes 评分计算5. 输出结果 IntelliGenesR 安装包1. 特征选择2. 模型训练和评估3. I-Genes 评分计…...
Java毕业设计:WML信息查询与后端信息发布系统开发
JAVAWML信息查询与后端信息发布系统实现 一、系统概述 本系统基于Java和WML(无线标记语言)技术开发,实现了移动设备上的信息查询与后端信息发布功能。系统采用B/S架构,服务器端使用Java Servlet处理请求,数据库采用MySQL存储信息࿰…...
