Java设计模式:工厂模式详解
引言
1. 工厂模式的定义
2. 工厂模式的类型
2.1 简单工厂模式
2.1.1 结构
2.1.2 示例代码
2.2 工厂方法模式
2.2.1 结构
2.2.2 示例代码
2.3 抽象工厂模式
2.3.1 结构
2.3.2 示例代码
3. 工厂模式的优点
4. 工厂模式的缺点
5. 实际应用场景
6. 总结
引言
工厂模式(Factory Pattern)是创建型设计模式之一,它提供了一种创建对象的最佳方式。在工厂模式中,我们不再直接通过
new
关键字来实例化对象,而是通过调用工厂方法来获取对象。这种方式将对象的创建和使用分离,提高了代码的灵活性和可维护性。
1. 工厂模式的定义
工厂模式是一种创建型设计模式,它提供了一个创建对象的接口,但允许子类决定实例化哪一个类。工厂方法让类的实例化推迟到子类。
2. 工厂模式的类型
工厂模式主要有以下几种类型:
- 简单工厂模式(Simple Factory)
- 工厂方法模式(Factory Method)
- 抽象工厂模式(Abstract Factory)
2.1 简单工厂模式
简单工厂模式不是严格意义上的设计模式,因为它并不符合开闭原则。但它提供了一个简单的对象创建机制。
2.1.1 结构
- 产品接口(Product Interface):定义产品的公共接口。
- 具体产品(Concrete Product):实现产品接口的具体类。
- 工厂类(Factory Class):包含创建产品的方法,根据传入的参数返回相应的产品实例。
2.1.2 示例代码
// 产品接口
interface Shape {void draw();
}// 具体产品
class Circle implements Shape {@Overridepublic void draw() {System.out.println("Drawing a Circle");}
}class Rectangle implements Shape {@Overridepublic void draw() {System.out.println("Drawing a Rectangle");}
}// 工厂类
class ShapeFactory {// 根据传入的形状类型创建相应的形状对象public static Shape getShape(String shapeType) {if (shapeType == null) {return null;}if (shapeType.equalsIgnoreCase("CIRCLE")) {return new Circle();} else if (shapeType.equalsIgnoreCase("RECTANGLE")) {return new Rectangle();}return null;}
}// 客户端代码
public class SimpleFactoryDemo {public static void main(String[] args) {Shape circle = ShapeFactory.getShape("CIRCLE");circle.draw();Shape rectangle = ShapeFactory.getShape("RECTANGLE");rectangle.draw();}
}
2.2 工厂方法模式
工厂方法模式定义了一个用于创建对象的接口,但由子类决定实例化哪一个类。工厂方法使一个类的实例化延迟到其子类。
2.2.1 结构
- 产品接口(Product Interface):定义产品的公共接口。
- 具体产品(Concrete Product):实现产品接口的具体类。
- 工厂接口(Factory Interface):声明创建产品的方法。
- 具体工厂(Concrete Factory):实现工厂接口,创建具体的产品实例。
2.2.2 示例代码
// 产品接口
interface Shape {void draw();
}// 具体产品
class Circle implements Shape {@Overridepublic void draw() {System.out.println("Drawing a Circle");}
}class Rectangle implements Shape {@Overridepublic void draw() {System.out.println("Drawing a Rectangle");}
}// 工厂接口
interface ShapeFactory {Shape createShape();
}// 具体工厂
class CircleFactory implements ShapeFactory {@Overridepublic Shape createShape() {return new Circle();}
}class RectangleFactory implements ShapeFactory {@Overridepublic Shape createShape() {return new Rectangle();}
}// 客户端代码
public class FactoryMethodDemo {public static void main(String[] args) {ShapeFactory circleFactory = new CircleFactory();Shape circle = circleFactory.createShape();circle.draw();ShapeFactory rectangleFactory = new RectangleFactory();Shape rectangle = rectangleFactory.createShape();rectangle.draw();}
}
2.3 抽象工厂模式
抽象工厂模式提供一个创建一系列相关或相互依赖对象的接口,而无需指定它们具体的类。
2.3.1 结构
- 抽象产品接口(Abstract Product Interface):定义一组产品接口。
- 具体产品(Concrete Product):实现抽象产品接口的具体类。
- 抽象工厂接口(Abstract Factory Interface):声明创建抽象产品的方法。
- 具体工厂(Concrete Factory):实现抽象工厂接口,创建具体的产品实例。
2.3.2 示例代码
// 抽象产品接口
interface Shape {void draw();
}interface Color {void fill();
}// 具体产品
class Circle implements Shape {@Overridepublic void draw() {System.out.println("Drawing a Circle");}
}class Rectangle implements Shape {@Overridepublic void draw() {System.out.println("Drawing a Rectangle");}
}class Red implements Color {@Overridepublic void fill() {System.out.println("Filling with Red color");}
}class Green implements Color {@Overridepublic void fill() {System.out.println("Filling with Green color");}
}// 抽象工厂接口
interface AbstractFactory {Shape createShape(String shapeType);Color createColor(String colorType);
}// 具体工厂
class ShapeFactory implements AbstractFactory {@Overridepublic Shape createShape(String shapeType) {if (shapeType.equalsIgnoreCase("CIRCLE")) {return new Circle();} else if (shapeType.equalsIgnoreCase("RECTANGLE")) {return new Rectangle();}return null;}@Overridepublic Color createColor(String colorType) {return null;}
}class ColorFactory implements AbstractFactory {@Overridepublic Shape createShape(String shapeType) {return null;}@Overridepublic Color createColor(String colorType) {if (colorType.equalsIgnoreCase("RED")) {return new Red();} else if (colorType.equalsIgnoreCase("GREEN")) {return new Green();}return null;}
}// 客户端代码
public class AbstractFactoryDemo {public static void main(String[] args) {AbstractFactory shapeFactory = new ShapeFactory();Shape circle = shapeFactory.createShape("CIRCLE");circle.draw();AbstractFactory colorFactory = new ColorFactory();Color red = colorFactory.createColor("RED");red.fill();}
}
3. 工厂模式的优点
- 封装性:对象的创建过程被封装在工厂方法中,客户端不需要知道具体的创建细节。
- 解耦:客户端与具体的产品类解耦,可以方便地更换具体的产品类。
- 扩展性:添加新的产品类时,只需扩展工厂类即可,不需要修改现有的代码。
- 一致性:所有对象都通过工厂方法创建,确保了创建的一致性和完整性。
4. 工厂模式的缺点
- 增加复杂度:引入了额外的工厂类,增加了系统的复杂度。
- 单一职责原则:工厂类可能变得非常庞大,违反了单一职责原则。
5. 实际应用场景
- 数据库访问层:根据不同的数据库类型(如 MySQL、Oracle),创建相应的数据库连接对象。
- 日志系统:根据不同的日志级别(如 DEBUG、INFO、ERROR),创建相应的日志记录器。
- 图形界面:根据不同的平台(如 Windows、Linux),创建相应的 UI 控件。
6. 总结
工厂模式是一种非常实用的设计模式,它可以提高代码的可维护性和扩展性。通过将对象的创建过程封装在工厂类中,客户端可以更加灵活地使用对象,而不必关心具体的创建细节。
相关文章:
Java设计模式:工厂模式详解
引言 1. 工厂模式的定义 2. 工厂模式的类型 2.1 简单工厂模式 2.1.1 结构 2.1.2 示例代码 2.2 工厂方法模式 2.2.1 结构 2.2.2 示例代码 2.3 抽象工厂模式 2.3.1 结构 2.3.2 示例代码 3. 工厂模式的优点 4. 工厂模式的缺点 5. 实际应用场景 6. 总结 引言 工厂模…...

《Python游戏编程入门》注-第3章1
《Python游戏编程入门》的第三章是“I/O、数据和字体:Trivia游戏”,介绍了print()函数、input()函数、异常处理以及文件的输入输出,最后根据以上内容完成了Trivia游戏。 本章的“3.1 了解Trivia游戏”介绍了Trivia游戏的界面和玩法。“3.2 P…...

Java爬虫:获取数据的入门详解
在数字化时代,数据已成为最宝贵的资产之一。无论是市场研究、客户洞察还是产品开发,获取大量数据并从中提取有价值的信息变得至关重要。Java,作为一种成熟且功能强大的编程语言,为编写爬虫提供了强大的支持。Java爬虫可以帮助我们…...

GAMES104:17 游戏引擎的玩法系统:高级AI-学习笔记
文章目录 课前QA一,层次任务网络(Hierarchical Tasks Network,HTN)1.1 HTN Framework1.2 HTN Task Types1.2.1 Primitive Task基本任务1.2.2 Compound Task符合任务 1.3 Planning1.4 Replan1.5 总结 二,目标导向行为规…...
【Unity】Unity中获取网络时间进行每日和每月刷新
直接上代码 using System; using System.Collections; using System.Collections.Generic; using UnityEngine;public class DateChecker : MonoBehaviour {private DateTime lastCheckedDate; //上次刷新日数据的日期private DateTime lastMonthUtc; //上次刷新月数据的日期T…...

微信小程序上传组件封装uploadHelper2.0使用整理
一、uploadHelper2.0使用步骤说明 uploadHelper.js ---上传代码封装库 cos-wx-sdk-v5.min.js---腾讯云,对象存储封装库 第一步,下载组件代码,放置到自己的小程序项目中 第二步、 创建上传对象,执行选择图片/视频 var _this th…...
力扣每日打卡挑战 3184. 构成整天的下标对数目 I
给你一个整数数组 hours,表示以 小时 为单位的时间,返回一个整数,表示满足 i < j 且 hours[i] hours[j] 构成 整天 的下标对 i, j 的数目。 整天 定义为时间持续时间是 24 小时的 整数倍 。 例如,1 天是 24 小时,…...

The First:Starknet如何让以太坊更快更安全?
随着区块链技术需求的持续增长,当前技术在可扩展性和隐私保护方面的局限性愈发凸显,以太坊网络便是其中的典型代表。为有效应对这些挑战,第二层扩展解决方案的重要性日益凸显。这些方案旨在将部分交易处理转移至以太坊主链之外,以…...
【计算机网络 - 基础问题】每日 3 题(五十三)
✍个人博客:https://blog.csdn.net/Newin2020?typeblog 📣专栏地址:http://t.csdnimg.cn/fYaBd 📚专栏简介:在这个专栏中,我将会分享 C 面试中常见的面试题给大家~ ❤️如果有收获的话,欢迎点赞…...

便携式移动消防炮:灵活灭火新选择
在当今快速发展的社会中,火灾安全问题一直是公众安全的重要组成部分。无论是家庭、办公场所还是大型工业区,火灾的发生都可能带来不可预测的巨大损失,传统消防固定系统往往无法迅速适应多变的火场环境,特别是对于那些发生在高层建…...

18.VScode写Java项目的教程
VScode写Java项目的教程 1.首先必选先安装Java解释器2.安装插件Java Extension Pack3.创建项目创建项目结构选择项目类型 4.测试结果源码内容 今天用一台老式笔记本写代码,IDEA跑不动就准备用VScode突然间就蒙了,怎么创建项目啊?于是就有了这…...

本地生活便民信息服务小程序源码系统 PHP+MySQL组合开发 带完整的安装代码包以及搭建部署教程
系统概述 地方门户分类信息网站源码系统是一个基于PHP和MySQL开发的强大平台,旨在帮助用户轻松搭建地方性的分类信息网站。该系统集成了众多实用功能,支持用户自由发帖、浏览和搜索各类信息,如二手交易、求职招聘、房屋租售、生活服务、商家…...

Java项目实战II基于微信小程序的原创音乐平台{UNIAPP+SSM+MySQL+Vue}(开发文档+数据库+源码)
目录 一、前言 二、技术介绍 三、系统实现 四、文档参考 五、核心代码 六、源码获取 全栈码农以及毕业设计实战开发,CSDN平台Java领域新星创作者,专注于大学生项目实战开发、讲解和毕业答疑辅导。获取源码联系方式请查看文末 一、前言 在数字音乐…...

【个人同步与备份】电脑(Windows)与手机/平板(Android)之间文件同步
文章目录 1. syncthing软件下载2. syncthing的使用2.1. 添加设备2.1.1. syncthing具备设备发现功能,因此安装好软件,只需确认设备信息是否对应即可2.1.2. 如果没有发现到,可以通过设备ID连接2.1.3. 设置GUI身份验证用户,让无关设备…...

代码随想录算法训练营第46期Day37,38,39,41
这几天晚上看比赛,就把刷题耽误了。还好是开新章节,前面的题都比较简单。 然后周天做完了又忘记发了 动态规划 确定dp数组(dp table)以及下标的含义确定递推公式dp数组如何初始化确定遍历顺序举例推导dp数 Day37前两道题太简单…...

点跟踪论文—RAFT: Recurrent All-Pairs Field Transforms for Optical Flow-递归的全对场光流变换
点目标跟踪论文—RAFT: Recurrent All-Pairs Field Transforms for Optical Flow-递归的全对场光流变换 读论文RAFT密集光流跟踪的笔记 RAFT是一种新的光流深度网络结构,由于需要基于点去做目标的跟踪,因此也是阅读了像素级别跟踪的一篇ECCV 2020的经典…...

jmeter学习(6)逻辑控制器-循环
循环执行 1、循环读取csv文件的值 2、foreach 读取变量,变量数字后缀有序递增,通过counter实现 ${__V(typeId${typeIdNum})} beansell断言 String typeIdNum vars.get("typeIdNum"); String response prev.getResponseDataAsString(); …...

unity学习笔记-安装与部署
unity学习笔记-安装与部署 unity & visual studio下载unityvisual studio 创建工程项目内的布局介绍初始化项目各目录介绍1. 场景视图(Scene)2. 游戏视图(Game)3. 层次结构视图(Hierarchy)4. 检查器视图…...
Django+MySQL接口开发完全指南
前言 本文将详细介绍如何使用Django结合MySQL数据库开发RESTful API接口。我们将从环境搭建开始,一步步实现一个完整的接口项目。 环境准备 首先需要安装以下组件: Python 3.8Django 4.2MySQL 8.0mysqlclientdjangorestframework 安装命令 # 创建虚…...
CentOS7上下载安装 Docker Compose
Docker Compose简要介绍(想直接看安装步骤的请跳转到[必要的安装步骤]) Docker Compose 是一个用于定义和管理多容器 Docker 应用的工具,它可以通过一个简单的 YAML 文件(docker-compose.yml)来配置应用程序的服务、网…...

测试微信模版消息推送
进入“开发接口管理”--“公众平台测试账号”,无需申请公众账号、可在测试账号中体验并测试微信公众平台所有高级接口。 获取access_token: 自定义模版消息: 关注测试号:扫二维码关注测试号。 发送模版消息: import requests da…...

React第五十七节 Router中RouterProvider使用详解及注意事项
前言 在 React Router v6.4 中,RouterProvider 是一个核心组件,用于提供基于数据路由(data routers)的新型路由方案。 它替代了传统的 <BrowserRouter>,支持更强大的数据加载和操作功能(如 loader 和…...
DockerHub与私有镜像仓库在容器化中的应用与管理
哈喽,大家好,我是左手python! Docker Hub的应用与管理 Docker Hub的基本概念与使用方法 Docker Hub是Docker官方提供的一个公共镜像仓库,用户可以在其中找到各种操作系统、软件和应用的镜像。开发者可以通过Docker Hub轻松获取所…...
线程与协程
1. 线程与协程 1.1. “函数调用级别”的切换、上下文切换 1. 函数调用级别的切换 “函数调用级别的切换”是指:像函数调用/返回一样轻量地完成任务切换。 举例说明: 当你在程序中写一个函数调用: funcA() 然后 funcA 执行完后返回&…...
大模型多显卡多服务器并行计算方法与实践指南
一、分布式训练概述 大规模语言模型的训练通常需要分布式计算技术,以解决单机资源不足的问题。分布式训练主要分为两种模式: 数据并行:将数据分片到不同设备,每个设备拥有完整的模型副本 模型并行:将模型分割到不同设备,每个设备处理部分模型计算 现代大模型训练通常结合…...

【OSG学习笔记】Day 16: 骨骼动画与蒙皮(osgAnimation)
骨骼动画基础 骨骼动画是 3D 计算机图形中常用的技术,它通过以下两个主要组件实现角色动画。 骨骼系统 (Skeleton):由层级结构的骨头组成,类似于人体骨骼蒙皮 (Mesh Skinning):将模型网格顶点绑定到骨骼上,使骨骼移动…...

自然语言处理——Transformer
自然语言处理——Transformer 自注意力机制多头注意力机制Transformer 虽然循环神经网络可以对具有序列特性的数据非常有效,它能挖掘数据中的时序信息以及语义信息,但是它有一个很大的缺陷——很难并行化。 我们可以考虑用CNN来替代RNN,但是…...

UR 协作机器人「三剑客」:精密轻量担当(UR7e)、全能协作主力(UR12e)、重型任务专家(UR15)
UR协作机器人正以其卓越性能在现代制造业自动化中扮演重要角色。UR7e、UR12e和UR15通过创新技术和精准设计满足了不同行业的多样化需求。其中,UR15以其速度、精度及人工智能准备能力成为自动化领域的重要突破。UR7e和UR12e则在负载规格和市场定位上不断优化…...

Spring数据访问模块设计
前面我们已经完成了IoC和web模块的设计,聪明的码友立马就知道了,该到数据访问模块了,要不就这俩玩个6啊,查库势在必行,至此,它来了。 一、核心设计理念 1、痛点在哪 应用离不开数据(数据库、No…...
基于matlab策略迭代和值迭代法的动态规划
经典的基于策略迭代和值迭代法的动态规划matlab代码,实现机器人的最优运输 Dynamic-Programming-master/Environment.pdf , 104724 Dynamic-Programming-master/README.md , 506 Dynamic-Programming-master/generalizedPolicyIteration.m , 1970 Dynamic-Programm…...