【Java】设计模式之单例模式与工厂模式
1、设计模式概念及分类
简单来说设计模式是被广大程序员们总结并认可的编码套路,其中最常用的莫过于单例模式与工厂模式,而单例模式也有更加细的分类,一起来学习一下这些模式的用法和特点吧。
2、单例模式
一个类只能被实例化出来一个对象
2.1、饿汉式
无论如何,都会创建出来一个对象 思路: 在类中直接实例化一个用来返回的对象,再为外界提供一个获取该对象的方法 缺点:有可能造成空间浪费
代码解释:
/**
单例模式-饿汉式
*/
public class ClassA {
//唯一的、全局的、私有的、用来返回的对象实例
private static ClassA ca=new ClassA();
//方法:用来被外界调用,从而获取该类的唯一实例
//static:为了使外界直接通过类名调用该方法
public static ClassA getClassA(){
return ca;
1
}
//私有化构造:避免外界通过构造创建该类的对象
private ClassA(){
}
}
public class Test {
public static void main(String[] args) {
ClassA ca1=ClassA.getClassA();
ClassA ca2=ClassA.getClassA();
System.out.println(ca1==ca2);//true
}
相当于类加载,ca1和ca2都是类对象,为同一个对象,要与类的对象有所区分。
2.2、懒汉式
思路:只有当需要创建唯一实例时,才会在对应方法中进行实例化 使用synchronized来同步方法 缺点:同步方法效率太慢,线程效率低
代码解释:
/**
单例模式-懒汉式
*/
public class ClassB {
//声明用来返回的对象引用
private static ClassB cb=null;
//synchronized:避免线程安全问题
public synchronized static ClassB getClassB(){
if (cb==null){
1
//非空判断,避免重复创建
cb=new ClassB();
}
return cb;
}
//私有化构造
private ClassB(){
}
}
这里利用了synchronized来防止重复创建实例化对象:如果事先没有创建,那就新创建,不会浪费空间。
2.2.1、懒汉式进阶版
思路:在保证线程安全的基础上,最大程度提高线程效率 使用synchronized来同步代码块
代码演示:
/**
单例模式-懒汉式进阶版
*/
public class ClassB2 {
//声明用来返回的对象引用
private static ClassB2 cb=null;
//synchronized:避免线程安全问题
public static ClassB2 getClassB2(){
if (cb==null){
1
//非空判断,避免重复创建
synchronized (ClassB2.class){
if (cb==null){
1
//二次校验,如果出现了线程安全问题,最大程度保证数据安全
cb=new ClassB2();
}
}
}
return cb;
}
//私有化构造
private ClassB2(){
}
}
同步代码块会使程序运行效率提升,因为此时只需时间片就可以执行此线程。
2.2.2、懒汉式之懒加载
思路:在懒汉式的基础上,将获取自己类实例的任务交给静态内部类完成
public class ClassC {
//声明用来返回的对象引用
private static ClassC cc=null;
//静态内部类:获取ClassC的唯一实例
private static class ClassC2{
1 //synchronized:避免线程安全问题
2 public static ClassC get(){
3
4
5 if (cc==null){
//非空判断,避免重复创建
synchronized (ClassC.class){
if (cc==null){
1
//二次校验,如果出现了线程安全问题,最大程度保证数据安全
cc=new ClassC();
}
}
}
return cc;
}
}
public static ClassC getClassC(){
return ClassC2.get();
1
}
//私有化构造
private ClassC(){
}
}
这种方式效果跟懒汉式的进阶类似,只不过是将加载交给了静态内部类,效率更高。
3、工厂模式
特点:
常用于框架 自身不再直接创建对象,交给 “工厂” 完成,需要对象时直接调用工厂的指定方法获取
步骤:
书写实体类,用来构建对象
书写.properties配置文件,存放工厂使用反射时需要的类信息
书写工厂类,创建对象
书写测试类
用一个实例演示:
3.1、书写实体类
public class Student {
private String name; private int age; private double score;
//此处省略getter与setter方法
public Student() {
}
public Student(String name, int age, double score) {
this.name = name;
this.age = age;
this.score = score;
}
@Override public String toString() {
return "Student{" +"name=" + name + +", age=" + age +", score=" + score +};
}
}
3.2、新建配置文件.properties
右键项目名创建一个后缀名为.properties的配置文件
文件内容: 键(自定义)=值(类的全限定名) 例如:StudentClassName=com.bz.entity.Student
结构特点: 键不可重复 等号左右无双引号 整条语句不要存在多余空格 末尾无分号 一行只能有一个键值对
3.3、书写工厂类并创建对象
/**
工厂类
*/
public class MyFactory {
//书写获取Student实例的方法
//static:方便直接通过类名调用
public static Student getStudent(){
Student stu=null; try ( //创建字节输入流对象 FileInputStream fis = new FileInputStream("Factory.properties"); //添加缓冲流 BufferedInputStream bis = new BufferedInputStream(fis); ) {
//创建用来接收配置文件信息的Properties集合Properties p = new Properties();//通过load方法将配置文件读取值集合中p.load(bis);//获取全限定名String str= p.getProperty("StudentClassName");//获取类对象Class c = Class.forName(str);//利用无参构造构建类的对象stu=(Student) c.newInstance();
}catch (FileNotFoundException e){
System.out.println("文件路径不正确");
}catch (IOException e){
System.out.println("读取失败");
}catch (Exception e){
System.out.println("未知异常!");e.printStackTrace();
}
return stu;
}
}
3.4、对工厂类测试
public class TestMyFactory {
public static void main(String[] args) {
1//利用工厂获取学生对象
2 Student stu = MyFactory.getStudent();
3 stu.setName("张三");
4 stu.setAge(20);
5 stu.setScore(78);
6 System.out.println(stu);
}
}
相关文章:
【Java】设计模式之单例模式与工厂模式
1、设计模式概念及分类 简单来说设计模式是被广大程序员们总结并认可的编码套路,其中最常用的莫过于单例模式与工厂模式,而单例模式也有更加细的分类,一起来学习一下这些模式的用法和特点吧。 2、单例模式 一个类只能被实例化出来一个对象…...
web自动化框架:selenium学习使用操作大全(Python版)
目录 一、浏览器驱动下载二、selenium-python安装(打开网站、操作元素)三、网页解析(HTML、xpath)四、selenium基本操作1、元素定位八种方法2、元素动态定位3、iframe切换4、填充表单_填充文本框5、填充表单_单选按钮6、填充表单_…...
boringssl EVP_aes_128_ecb实现
最近学习boringssl,发现没找到EVP_aes_128_ecb在哪里实现的 饶了一大圈,发现它的定义很无语 #define EVP_CIPHER_FUNCTION(keybits, mode) \const EVP_CIPHER *EVP_aes_##keybits##_##mode(void) { \return aes_##keybits##_##mode##_gene…...
vxe-table中树形结构
如图,同事让帮忙实现一个需求 从二级树节点开始,同时选中的只能有一个二级树节点,选中的二级树节点之下的子节点都可以被选中。否则不能被选中 直接上代码 需要注意的是,文中树状图传递的数据是打平的数据,设置代码是…...
Linux命令查看CPU、内存、IO使用情况简单介绍
文章目录 1. CPU相关介绍1.1 物理CPU1.2 物理CPU内核1.3 逻辑CPU1.4 几核几线程1.5 CPU设计图 2. top 查看系统负载、CPU使用情况2.1 系统整体的统计信息2.2 进程信息2.3 top命令使用 3. lscpu 显示有关 CPU 架构的信息4. free 查看内存信息5. iostat 查看io信息 1. CPU相关介绍…...
RPC框架的核心是什么
文章目录 什么是 RPC封装的艺术(如何隐藏底层逻辑)协议的实现序列化和反序列化(编解码)总结 什么是 RPC 首先思考这样一个问题,假设你不知道任何框架,现在有两台机器,每台机器上有一个服务&…...
直播、AI赋能,美团披着荆棘前行
随着互联网流量红利逐渐消退,阿里、抖音、腾讯、拼多多、快手、小红书等各赛道玩家,为了寻求新的增量,纷纷“卷”向本地生活,开始入侵美团的腹地。然而,哪怕巨头环伺,美团仍然展现出了其独特的竞争力&#…...
提升代码逻辑的感觉——python循环语句
提升代码逻辑的感觉——python循环语句 简介 循环是编程中的一个非常重要的概念,它用于处理重复性任何和迭代草错,通过循环我们能优化并简化代码,提高代码的可维护性,在Python中循环是一种控制结构,允许我们重复执行…...
【ARM Coresight 系列文章 20 -- linux perf 与 ARM coresight】
文章目录 1.1 Perf Introduction1.1.1 Perf 架构图1.1.2 Perf Tools 介绍1.1.3 Perf 命令介绍1.2 Events1.2.1 Perf 与 PMU 的关系1.2.2 Hardware events1.2.1.1 linux perf 事件分类1.2.2 Software Events1.2.3 Tracepoint Events1.3 Perf 工具使用1.4 用户态开发1.4.1 用户态…...
微服务之Nacos
1 版本说明 官网地址: https://github.com/alibaba/spring-cloud-alibaba/wiki/%E7%89%88%E6%9C%AC%E8%AF%B4%E6%98%8E 1.1 2021.x 分支 适配 SpringBoot 2.4, Spring Cloud 2021.x 版本及以上的Spring Cloud Alibaba 版本如下表(最新版本用*标记&am…...
jvm 新生代的区域划分
虚拟机将内存分为一块较大的 Eden 空间和两块较小的 Survivor 空间,每次分配内存只使用 Eden 和其中一块 Survivor。发生垃圾收集时,将 Eden 和 Survivor 中仍然存活的对象一次性复制到另外一块 Survivor 空间上,然后直接清理掉 Eden 和已用过…...
【C++】对于string的补充(成员函数c_str()、大小写转换、字符串和实数之间的相互转换)
前言 本篇文章记录的是一些关于string的补充说明 string与const char*之间的相互转换 const char* 转换成string 在C中存在着从const char到string的隐式类型转换,换句话说,如果一个函数的参数类型是string类,直接传入const char类型的参…...
华为OD机试真题【羊狼农夫过河】
1、题目描述 【羊、狼、农夫过河】 羊、狼、农夫都在岸边,当羊的数量小于狼的数量时,狼会攻击羊,农夫则会损失羊。农夫有一艘容量固定的船,能够承载固定数量的动物。要求求出不损失羊情况下将全部羊和狼运到对岸需要的最小次数。…...
【线性代数-3Blue1Brown】- 5 三维空间的线性变换
飞书原文档:Docs...
Maven入门教程(二):idea/Eclipse使用Maven
Maven入门教程(一):安装Maven环境 4.开发工具配置 4.1 idea配置 idea有多个版本,配置是一样的,只是配置页面的入口不一样 旧版idea 新版idea 4.2 Eclipse配置 打开Eclipse,菜单中选择:Window -> Preference ->…...
【MySQL】MySQL里的用户账户和角色是什么?如何管理?
用户(user)验证和授权创建用户账户连接服务器查看用户账户设置 角色(role)创建角色 操作用户帐户和角色重命名删除 感谢 💖 用户(user) 在MySQL中,用户是数据库访问的主要实体。每个…...
vbs病毒
vbs脚本:VBS脚本病毒原理分析和防范 疯狂代码 http://CrazyCoder.cn/ Sh t t p : / C r a z y C o d e r . c n / S e c u r i t y / Ar t i c l e 7 2 0 0 8 . h t m l 网络流行让我们世界变得更加美好但它也有让人不愉快时候当您收到封主题为1LoveYou” 邮件用兴奋 得几乎快发…...
用Java实现Huffman编码
文章目录 前言一、实现思路二、准备Huffman结点三、主要实现 前言 在使用http1.1协议传输数据的时候,会有一些固定的字段,比如cookie、编码方式、接收的数据类型,另外会有一些大量重复的字段造成请求报文过于冗长,为了解决这个问…...
day-04 基于UDP的服务器端/客户端
一.理解UDP (一)UDP套接字的特点 UDP套接字具有以下特点: 无连接性:UDP是一种无连接的协议,这意味着在发送数据之前,不需要在发送方和接收方之间建立连接。每个UDP数据包都是独立的,它们可以独…...
FFmpeg rtp rtp_mpegts的区别
rtp 在FFmpeg中,rtpenc是一个用于将音视频数据封装成RTP(Real-time Transport Protocol)数据包并发送到网络上的编码器。RTP是一种用于实时传输音视频数据的协议,常用于视频会议、流媒体等场景。 rtpenc可以将音视频数据封装成R…...
React Native 导航系统实战(React Navigation)
导航系统实战(React Navigation) React Navigation 是 React Native 应用中最常用的导航库之一,它提供了多种导航模式,如堆栈导航(Stack Navigator)、标签导航(Tab Navigator)和抽屉…...
UE5 学习系列(三)创建和移动物体
这篇博客是该系列的第三篇,是在之前两篇博客的基础上展开,主要介绍如何在操作界面中创建和拖动物体,这篇博客跟随的视频链接如下: B 站视频:s03-创建和移动物体 如果你不打算开之前的博客并且对UE5 比较熟的话按照以…...
解锁数据库简洁之道:FastAPI与SQLModel实战指南
在构建现代Web应用程序时,与数据库的交互无疑是核心环节。虽然传统的数据库操作方式(如直接编写SQL语句与psycopg2交互)赋予了我们精细的控制权,但在面对日益复杂的业务逻辑和快速迭代的需求时,这种方式的开发效率和可…...
《用户共鸣指数(E)驱动品牌大模型种草:如何抢占大模型搜索结果情感高地》
在注意力分散、内容高度同质化的时代,情感连接已成为品牌破圈的关键通道。我们在服务大量品牌客户的过程中发现,消费者对内容的“有感”程度,正日益成为影响品牌传播效率与转化率的核心变量。在生成式AI驱动的内容生成与推荐环境中࿰…...
MODBUS TCP转CANopen 技术赋能高效协同作业
在现代工业自动化领域,MODBUS TCP和CANopen两种通讯协议因其稳定性和高效性被广泛应用于各种设备和系统中。而随着科技的不断进步,这两种通讯协议也正在被逐步融合,形成了一种新型的通讯方式——开疆智能MODBUS TCP转CANopen网关KJ-TCPC-CANP…...
Mac软件卸载指南,简单易懂!
刚和Adobe分手,它却总在Library里给你写"回忆录"?卸载的Final Cut Pro像电子幽灵般阴魂不散?总是会有残留文件,别慌!这份Mac软件卸载指南,将用最硬核的方式教你"数字分手术"࿰…...
解决本地部署 SmolVLM2 大语言模型运行 flash-attn 报错
出现的问题 安装 flash-attn 会一直卡在 build 那一步或者运行报错 解决办法 是因为你安装的 flash-attn 版本没有对应上,所以报错,到 https://github.com/Dao-AILab/flash-attention/releases 下载对应版本,cu、torch、cp 的版本一定要对…...
DeepSeek 技术赋能无人农场协同作业:用 AI 重构农田管理 “神经网”
目录 一、引言二、DeepSeek 技术大揭秘2.1 核心架构解析2.2 关键技术剖析 三、智能农业无人农场协同作业现状3.1 发展现状概述3.2 协同作业模式介绍 四、DeepSeek 的 “农场奇妙游”4.1 数据处理与分析4.2 作物生长监测与预测4.3 病虫害防治4.4 农机协同作业调度 五、实际案例大…...
Linux --进程控制
本文从以下五个方面来初步认识进程控制: 目录 进程创建 进程终止 进程等待 进程替换 模拟实现一个微型shell 进程创建 在Linux系统中我们可以在一个进程使用系统调用fork()来创建子进程,创建出来的进程就是子进程,原来的进程为父进程。…...
docker 部署发现spring.profiles.active 问题
报错: org.springframework.boot.context.config.InvalidConfigDataPropertyException: Property spring.profiles.active imported from location class path resource [application-test.yml] is invalid in a profile specific resource [origin: class path re…...
