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

【设计模式】工厂模式(定义 | 特点 | Demo入门讲解)

文章目录

    • 定义
    • 简单工厂模式
      • 案例 | 代码
        • Phone顶层接口设计
        • Meizu品牌类
        • Xiaomi品牌类
        • PhoneFactory工厂类
        • Customer 消费者类
    • 工厂方法模式
      • 案例 | 代码
        • PhoneFactory工厂类
    • Java高级特性---工厂模式与反射的高阶玩法
        • 方案:反射+工厂模式
    • 总结

其实工厂模式就是用一个代理类帮你创建管理对象,你就不用在代码层面去不断new对象的使用了。

创建对象和调用对象两者之间会解耦!

定义

工厂模式有三种:

  • 简单工厂模式
  • 工厂方法模式
  • 抽象方法模式

简单工厂模式

简单工厂模式也叫静态工厂模式。

举个例子:你要去买一台手机,你不用关心手机是怎么生产出来的,里面的零件具体又是怎么制造的,这些通通都交给工厂去处理,你尽管去买手机就好了。

image-20240705131418461

案例 | 代码

Phone顶层接口设计
/*** @author linghu* @date 2024/7/5 11:08*/
public interface Phone {void getBrand();
}
Meizu品牌类
/*** @author linghu* @date 2024/7/5 11:09*/
public class Meizu implements Phone{@Overridepublic void getBrand() {System.out.println("魅族");}
}
Xiaomi品牌类
/*** @author linghu* @date 2024/7/5 12:35*/
public class Xiaomi implements Phone{@Overridepublic void getBrand() {System.out.println("小米");}
}
PhoneFactory工厂类

这个是简单工厂模式,又叫静态工厂,所以方法自然是静态的!而且这个工厂类负责帮我们创建对象,并且返回对象!

在这里我们可以先用硬编码的方式:

/*** @author linghu* @date 2024/7/5 12:35*/
public class PhoneFactory {public static Phone getPhone(String phone){if ("小米".equals(phone)){return new Xiaomi();} else if ("魅族".equals(phone)) {return new Meizu();}else {return null;}}
}
Customer 消费者类

这个类就类似一个客户端的作用把。

/*** @author linghu* @date 2024/7/5 12:38*/
public class Customer {public static void main(String[] args) {PhoneFactory.getPhone("小米").getBrand();PhoneFactory.getPhone("魅族").getBrand();}
}

image-20240705132326792

工厂方法模式

工厂方法模式就是在上面简单工厂模式的基础上做了一些修改,具体的做法就是为每种不同品牌的手机都创建一个工厂独立生产。

image-20240705140352151

案例 | 代码

如上,其他代码都不变,变化的部分是工厂那部分!

PhoneFactory工厂类

首先修改一下PhoneFactory工厂类,将:

/*** @author linghu* @date 2024/7/5 12:35*/
public class PhoneFactory {public static Phone getPhone(String phone){if ("小米".equals(phone)){return new Xiaomi();} else if ("魅族".equals(phone)) {return new Meizu();}else {return null;}}
}

修改为:

/*** @author linghu* @date 2024/7/5 12:35*/
public interface PhoneFactory {Phone getPhone();
}

新增的两个工厂类:

/*** @author linghu* @date 2024/7/5 14:09*/
public class MeizuFactory implements PhoneFactory{@Overridepublic Phone getPhone() {return new Meizu();}
}
/*** @author linghu* @date 2024/7/5 14:08*/
public class XiaomiFactory implements PhoneFactory{@Overridepublic Phone getPhone() {return new Xiaomi();}
}

Customer 消费者类:

/*** @author linghu* @date 2024/7/5 12:38*/
public class Customer {public static void main(String[] args) {
//        PhoneFactory.getPhone("小米").getBrand();
//        PhoneFactory.getPhone("魅族").getBrand();Phone xiaomi=new XiaomiFactory().getPhone();Phone meizu=new MeizuFactory().getPhone();xiaomi.getBrand();meizu.getBrand();}
}

image-20240705142134386

Java高级特性—工厂模式与反射的高阶玩法

我们先回顾一下上面的工厂模式用法,列举一下会发现:

  • 简单工厂模式的局限性在于:如果我们扩充手机的品牌,就会违反 开闭原则
  • 工厂方法模式的局限性在于:我们扩充手机品牌需要不断new更多对象,这是耦合的最大元凶!!
方案:反射+工厂模式

PhoneFactory工厂类

/*** @author linghu* @date 2024/7/5 12:35*/
public class PhoneFactory {public static Phone getInstance(String origin) throws ClassNotFoundException, InstantiationException, IllegalAccessException {Class<?> cls = Class.forName("com.linghu.factory." + origin);Phone brand=(Phone)cls.newInstance();return brand;}
}

Customer 消费者类

这个时候我们无需再new更多对象了,也不用写死了:

/*** @author linghu* @date 2024/7/5 12:38*/
public class Customer {public static void main(String[] args) throws ClassNotFoundException, InstantiationException, IllegalAccessException {
//        PhoneFactory.getPhone("小米").getBrand();
//        PhoneFactory.getPhone("魅族").getBrand();
//        Phone xiaomi=new XiaomiFactory().getPhone();
//        Phone meizu=new MeizuFactory().getPhone();
//        xiaomi.getBrand();
//        meizu.getBrand();PhoneFactory.getInstance("Xiaomi").getBrand();}
}

image-20240705161002362

输入类名以后,反射创建对象,再通过工厂返回相关对象!!

总结

第一个静态工厂模式:在实际去开发中会发现比较常用,尽管上面讲了不符合(面向对象)OOP原则。
第二个工厂方法模式:不修改工厂类的前提,也就是说不修改已有类,实现对扩展是开发,对修改关闭。

相关文章:

【设计模式】工厂模式(定义 | 特点 | Demo入门讲解)

文章目录 定义简单工厂模式案例 | 代码Phone顶层接口设计Meizu品牌类Xiaomi品牌类PhoneFactory工厂类Customer 消费者类 工厂方法模式案例 | 代码PhoneFactory工厂类 Java高级特性---工厂模式与反射的高阶玩法方案&#xff1a;反射工厂模式 总结 其实工厂模式就是用一个代理类帮…...

Linux之计划和日志

计划任务 计划任务概念解析 在Linux操作系统中,除了用户即时执行的命令操作以外,还可以配置在指定的时间、指定的日期执行预先计划好的系统管理任务(如定期备份、定期采集监测数据)。通过安装at和crontabs这两个系统服务实现一次性、周期性计划任务的功能,并分别通过at、…...

C++ 多态篇

文章目录 1. 多态的概念和实现1.1 概念1.2 实现1.2.1 协变1.2.2 析构函数1.2.3 子类虚函数不加virtual 2. C11 final和override3.1 final3.2 override 3. 函数重载、重写与隐藏4. 多态的原理5. 抽象类6.单继承和多继承的虚表6.1 单继承6.2 多继承 7. 菱形继承的虚表(了解)7.1 菱…...

【LVGL-SquareLine Studio】

LVGL-SquareLine Studio ■ SquareLine Studio-官网下载地址■ SquareLine Studio-参考博客■ SquareLine Studio-安装■ SquareLine Studio-汉化■ SquareLine Studio-■ SquareLine Studio-■ SquareLine Studio-■ SquareLine Studio-■ SquareLine Studio- ■ SquareLine S…...

mysqli 与mysql 区别和联系, 举例说明

mysqli是一种PHP的扩展&#xff0c;用于与MySQL数据库进行交互。它提供了一套面向对象的接口&#xff0c;可以更方便地操作数据库。MySQL是一种关系型数据库管理系统&#xff0c;用于存储和管理数据。 区别&#xff1a; mysqli是MySQL的扩展&#xff0c;而不是单独的数据库管…...

【SpringCloud应用框架】Nacos安装和服务提供者注册

第二章 Spring Cloud Alibaba Nacos之Nacos安装和服务提供者注册 文章目录 Nacos介绍为何使用Nacos&#xff1f;一、Nacos下载和安装1. 下载2. 安装Linux/Unix/MacWindows 二、Nacos服务提供者注册1. Nacos代替Eureka2. Nacos服务注册中心3. 引入Nacos Discovery进行服务注册/发…...

英语学习交流小程序的设计

管理员账户功能包括&#xff1a;系统首页&#xff0c;个人中心&#xff0c;用户管理&#xff0c;每日打卡管理&#xff0c;备忘录管理&#xff0c;学习计划管理&#xff0c;学习资源管理&#xff0c;论坛交流 微信端账号功能包括&#xff1a;系统首页&#xff0c;学习资源&…...

实现Java多线程中的线程间通信

实现Java多线程中的线程间通信 大家好&#xff0c;我是微赚淘客系统3.0的小编&#xff0c;也是冬天不穿秋裤&#xff0c;天冷也要风度的程序猿&#xff01; 1. 线程间通信的基本概念 在线程编程中&#xff0c;线程间通信是指多个线程之间通过共享内存或消息传递的方式进行交…...

C++模板元编程(一)——可变参数模板

这个系列主要记录C模板元编程的常用语法 文章目录 引言语法应用函数模板可变参数的打印可变参数的最小/最大函数 类模板 参考文献 引言 在C11之前&#xff0c;函数模板和类模板只支持含有固定数量的模板参数。C11增强了模板功能&#xff0c;允许模板定义中包含任意个(包括0个)…...

kafka中

Kafka RocketMQ概述 RabbitMQ概述 ActiveMQ概述 ZeroMQ概述 MQ对比选型 适用场景-从公司基础建设力量角度出发 适用场景-从业务场景出发 Kafka配置介绍 运行Kafka 安装ELAK 配置EFAK EFAK界面 KAFKA常用术语 Kafka常用指令 Kafka中消息读取 单播消息 group.id 相同 多播消息 g…...

Android 获取当前电池状态

在 API 级别 23 上获取充电状态 要在 API 级别 23 上获取电池的当前状态&#xff0c;只需使用电池管理器系统服务&#xff1a; BatteryManager batteryManager (BatteryManager) getSystemService(BATTERY_SERVICE); boolean isCharging batteryManager.isCharging();使用 S…...

【JVM 的内存模型】

1. JVM内存模型 下图为JVM内存结构模型&#xff1a; 两种执行方式&#xff1a; 解释执行&#xff1a;JVM是由C语言编写的&#xff0c;其中有C解释器&#xff0c;负责先将Java语言解释翻译为C语言。缺点是经过一次JVM翻译&#xff0c;速度慢一点。JIT执行&#xff1a;JIT编译器…...

【雷丰阳-谷粒商城 】【分布式高级篇-微服务架构篇】【17】认证服务01—短信/邮件/异常/MD5

持续学习&持续更新中… 守破离 【雷丰阳-谷粒商城 】【分布式高级篇-微服务架构篇】【17】认证服务01 环境搭建验证码倒计时短信服务邮件服务验证码短信形式&#xff1a;邮件形式&#xff1a; 异常机制MD5参考 环境搭建 C:\Windows\System32\drivers\etc\hosts 192.168.…...

geom buffer制作

1. auto buffer_geom line_string->buffer(15);//buffer //这个是x和y各扩大段15个单位 auto buffer_geom line_string->buffer(15);//buffer //这个是x和y各扩大段15米 获取buffer坐标 auto boundary buffer_geom->getBoundary(); auto boundary_coords boun…...

微软正在放弃React

最近&#xff0c;微软Edge团队撰写了一篇文章&#xff0c;介绍了微软团队如何努力提升Edge浏览器的性能。但在文中&#xff0c;微软对React提出了批评&#xff0c;并宣布他们将不再在Edge浏览器的开发中使用React。 我将详细解析他们的整篇文章内容&#xff0c;探讨这一决定对…...

U盘非安全退出后的格式化危机与高效恢复策略

在数字化时代&#xff0c;U盘作为数据存储与传输的重要工具&#xff0c;其数据安全备受关注。然而&#xff0c;一个常见的操作失误——U盘没有安全退出便直接拔出&#xff0c;随后再插入时却遭遇“需要格式化”的提示&#xff0c;这不仅让用户措手不及&#xff0c;更可能意味着…...

安卓虚拟位置修改

随着安卓系统的不断更新&#xff0c;确保软件和应用与最新系统版本的兼容性变得日益重要。本文档旨在指导用户如何在安卓14/15系统上使用特定的功能。 2. 系统兼容性更新 2.1 支持安卓14/15&#xff1a;更新了对安卓14/15版本的支持&#xff0c;确保了软件的兼容性。 2.2 路…...

大数据面试题之Presto[Trino](5)

目录 Presto的扩展性如何&#xff1f; Presto如何与Hadoop生态系统集成&#xff1f; Presto是否可以连接到NoSQL数据库&#xff1f; 如何使用Presto查询Kafka中的数据&#xff1f; Presto与Spark SQL相比有何优势和劣势&#xff1f; Presto如何与云服务集成&#xff1…...

对编程开发人员在今年的一些建议

一、今年的大环境 这几天身体不太好&#xff0c;又不断看到地狱级的就业问题。所以有些想法想和大家分享一下&#xff0c;并提出自己的一些想法和建议。今年的大环境不好&#xff0c;做为非专业人士&#xff0c;咱们也不分析&#xff0c;以免贻笑大方。但针对大环境下的计算机…...

VSCode设置好看清晰的字体!中文用鸿蒙,英文用Jetbrains Mono

一、中文字体——HarmonyOS Sans SC 1、下载字体 官网地址&#xff1a;https://developer.huawei.com/consumer/cn/design/resource/ 直接下载&#xff1a;https://communityfile-drcn.op.dbankcloud.cn/FileServer/getFile/cmtyPub/011/111/111/0000000000011111111.20230517…...

FastAPI 教程:从入门到实践

FastAPI 是一个现代、快速&#xff08;高性能&#xff09;的 Web 框架&#xff0c;用于构建 API&#xff0c;支持 Python 3.6。它基于标准 Python 类型提示&#xff0c;易于学习且功能强大。以下是一个完整的 FastAPI 入门教程&#xff0c;涵盖从环境搭建到创建并运行一个简单的…...

ESP32读取DHT11温湿度数据

芯片&#xff1a;ESP32 环境&#xff1a;Arduino 一、安装DHT11传感器库 红框的库&#xff0c;别安装错了 二、代码 注意&#xff0c;DATA口要连接在D15上 #include "DHT.h" // 包含DHT库#define DHTPIN 15 // 定义DHT11数据引脚连接到ESP32的GPIO15 #define D…...

Nuxt.js 中的路由配置详解

Nuxt.js 通过其内置的路由系统简化了应用的路由配置&#xff0c;使得开发者可以轻松地管理页面导航和 URL 结构。路由配置主要涉及页面组件的组织、动态路由的设置以及路由元信息的配置。 自动路由生成 Nuxt.js 会根据 pages 目录下的文件结构自动生成路由配置。每个文件都会对…...

Unit 1 深度强化学习简介

Deep RL Course ——Unit 1 Introduction 从理论和实践层面深入学习深度强化学习。学会使用知名的深度强化学习库&#xff0c;例如 Stable Baselines3、RL Baselines3 Zoo、Sample Factory 和 CleanRL。在独特的环境中训练智能体&#xff0c;比如 SnowballFight、Huggy the Do…...

网络编程(UDP编程)

思维导图 UDP基础编程&#xff08;单播&#xff09; 1.流程图 服务器&#xff1a;短信的接收方 创建套接字 (socket)-----------------------------------------》有手机指定网络信息-----------------------------------------------》有号码绑定套接字 (bind)--------------…...

为什么要创建 Vue 实例

核心原因:Vue 需要一个「控制中心」来驱动整个应用 你可以把 Vue 实例想象成你应用的**「大脑」或「引擎」。它负责协调模板、数据、逻辑和行为,将它们变成一个活的、可交互的应用**。没有这个实例,你的代码只是一堆静态的 HTML、JavaScript 变量和函数,无法「活」起来。 …...

安卓基础(Java 和 Gradle 版本)

1. 设置项目的 JDK 版本 方法1&#xff1a;通过 Project Structure File → Project Structure... (或按 CtrlAltShiftS) 左侧选择 SDK Location 在 Gradle Settings 部分&#xff0c;设置 Gradle JDK 方法2&#xff1a;通过 Settings File → Settings... (或 CtrlAltS)…...

AI语音助手的Python实现

引言 语音助手(如小爱同学、Siri)通过语音识别、自然语言处理(NLP)和语音合成技术,为用户提供直观、高效的交互体验。随着人工智能的普及,Python开发者可以利用开源库和AI模型,快速构建自定义语音助手。本文由浅入深,详细介绍如何使用Python开发AI语音助手,涵盖基础功…...

Unity VR/MR开发-VR开发与传统3D开发的差异

视频讲解链接&#xff1a;【XR马斯维】VR/MR开发与传统3D开发的差异【UnityVR/MR开发教程--入门】_哔哩哔哩_bilibili...

链式法则中 复合函数的推导路径 多变量“信息传递路径”

非常好&#xff0c;我们将之前关于偏导数链式法则中不能“约掉”偏导符号的问题&#xff0c;统一使用 二重复合函数&#xff1a; z f ( u ( x , y ) , v ( x , y ) ) \boxed{z f(u(x,y),\ v(x,y))} zf(u(x,y), v(x,y))​ 来全面说明。我们会展示其全微分形式&#xff08;偏导…...