当前位置: 首页 > 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…...

SpringBoot新手快速入门系列教程四:创建第一个SringBoot的API

首先我们用IDEA新建一个项目&#xff0c;请将这些关键位置按照我的设置设置一下 接下来我将要带着你一步一步创建一个Get请求和Post请求&#xff0c;通过客户端请求的参数&#xff0c;以json格式返回该参数{“message”:"Hello"} 1,先在IDE左上角把这里改为文件模式…...

第1集《修习止观坐禅法要》

《修习止观坐禅法要》诸位法师&#xff0c;诸位学员&#xff0c;阿弥院佛&#xff01; 我们今天能够暂时放下世间的尘劳&#xff0c;大家在一起研究佛法的课程&#xff0c;这件事情在我们的生命当中是非常的稀有难得。 基本上&#xff0c;我们佛法的修习目的是追求身心的安乐…...

markdown变量引用

格式 变量定义通常是路径或网络链接 变量测试...

如何使用echart做K线图

使用ECharts制作K线图需要先引入ECharts的库文件&#xff0c;然后通过调用相应的API来配置和渲染K线图。以下是一个简单的示例代码&#xff1a; // 引入ECharts库文件 <script src"https://cdn.jsdelivr.net/npm/echarts5.0.0/dist/echarts.min.js"></scri…...

Spring Boot应用使用GraalVM本地编译相关配置

1. 介绍 Java应用程序可以通过Graalvm Native Image提前编译生成与本地机器相关的可执行文件。与在JVM执行java程序相比&#xff0c;Native Image占用内存更小和启动速度更快。 从spring boot3开始支持GraalVM Native Image&#xff0c;因此要使用此特性&#xff0c;需要把sp…...

代码的坏味道——长函数

前言&#xff1a;一个函数应该尽量做一件事情&#xff0c;如果非要做多个事情&#xff0c;要做函数提取&#xff0c;每次迭代应该考虑到是否有重复代码或者可以优化的代码。 长函数&#xff1a;长函数的产生&#xff1a; 逻辑是平铺直叙的需求迭代没有考虑优化&#xff0c;一次…...

【机器学习】基于密度的聚类算法:DBSCAN详解

&#x1f308;个人主页: 鑫宝Code &#x1f525;热门专栏: 闲话杂谈&#xff5c; 炫酷HTML | JavaScript基础 ​&#x1f4ab;个人格言: "如无必要&#xff0c;勿增实体" 文章目录 基于密度的聚类算法&#xff1a;DBSCAN详解引言DBSCAN的基本概念点的分类聚类过…...

Qt 网络编程 网络信息获取操作

学习目标&#xff1a;网络信息获取操作 前置环境 运行环境:qt creator 4.12 学习内容 一、Qt 网络编程基础 Qt 直接提供了网络编程模块,包括基于 TCP/IP 的客户端和服务器相关类,如 QTcpSocket/QTcpServer 和 QUdpSocket,以及实现 HTTP、FTP 等协议的高级类,如 QNetworkRe…...

linux中的进程以及进程管理

程序和进程的区别和联系 程序&#xff08;Program&#xff09;&#xff1a; 程序是一组指令的集合&#xff0c;通常存储在磁盘或其他存储设备上&#xff0c;是一种静态的概念。程序本身并没有运行&#xff0c;它只是一个可执行的文件或脚本&#xff0c;包含了一系列的指令和数…...

pyecharts可视化案例大全(11~20)

pyecharts可视化案例大全(11~20) 十一、设置动画效果十二、直方图带视觉组件十三、设置渐变色(线性渐变)十四、设置渐变色(径向渐变)十五、设置分割线十六、设置分隔区域十七、面积图十八、堆叠面积图十九、自定义线样式二十、折线图平滑处理十一、设置动画效果 在图表加载前…...