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

【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…...

大数据学习栈记——Neo4j的安装与使用

本文介绍图数据库Neofj的安装与使用,操作系统:Ubuntu24.04,Neofj版本:2025.04.0。 Apt安装 Neofj可以进行官网安装:Neo4j Deployment Center - Graph Database & Analytics 我这里安装是添加软件源的方法 最新版…...

【Linux】C语言执行shell指令

在C语言中执行Shell指令 在C语言中&#xff0c;有几种方法可以执行Shell指令&#xff1a; 1. 使用system()函数 这是最简单的方法&#xff0c;包含在stdlib.h头文件中&#xff1a; #include <stdlib.h>int main() {system("ls -l"); // 执行ls -l命令retu…...

3.3.1_1 检错编码(奇偶校验码)

从这节课开始&#xff0c;我们会探讨数据链路层的差错控制功能&#xff0c;差错控制功能的主要目标是要发现并且解决一个帧内部的位错误&#xff0c;我们需要使用特殊的编码技术去发现帧内部的位错误&#xff0c;当我们发现位错误之后&#xff0c;通常来说有两种解决方案。第一…...

Objective-C常用命名规范总结

【OC】常用命名规范总结 文章目录 【OC】常用命名规范总结1.类名&#xff08;Class Name)2.协议名&#xff08;Protocol Name)3.方法名&#xff08;Method Name)4.属性名&#xff08;Property Name&#xff09;5.局部变量/实例变量&#xff08;Local / Instance Variables&…...

定时器任务——若依源码分析

分析util包下面的工具类schedule utils&#xff1a; ScheduleUtils 是若依中用于与 Quartz 框架交互的工具类&#xff0c;封装了定时任务的 创建、更新、暂停、删除等核心逻辑。 createScheduleJob createScheduleJob 用于将任务注册到 Quartz&#xff0c;先构建任务的 JobD…...

学习STC51单片机31(芯片为STC89C52RCRC)OLED显示屏1

每日一言 生活的美好&#xff0c;总是藏在那些你咬牙坚持的日子里。 硬件&#xff1a;OLED 以后要用到OLED的时候找到这个文件 OLED的设备地址 SSD1306"SSD" 是品牌缩写&#xff0c;"1306" 是产品编号。 驱动 OLED 屏幕的 IIC 总线数据传输格式 示意图 …...

vue3 定时器-定义全局方法 vue+ts

1.创建ts文件 路径&#xff1a;src/utils/timer.ts 完整代码&#xff1a; import { onUnmounted } from vuetype TimerCallback (...args: any[]) > voidexport function useGlobalTimer() {const timers: Map<number, NodeJS.Timeout> new Map()// 创建定时器con…...

【服务器压力测试】本地PC电脑作为服务器运行时出现卡顿和资源紧张(Windows/Linux)

要让本地PC电脑作为服务器运行时出现卡顿和资源紧张的情况&#xff0c;可以通过以下几种方式模拟或触发&#xff1a; 1. 增加CPU负载 运行大量计算密集型任务&#xff0c;例如&#xff1a; 使用多线程循环执行复杂计算&#xff08;如数学运算、加密解密等&#xff09;。运行图…...

JavaScript基础-API 和 Web API

在学习JavaScript的过程中&#xff0c;理解API&#xff08;应用程序接口&#xff09;和Web API的概念及其应用是非常重要的。这些工具极大地扩展了JavaScript的功能&#xff0c;使得开发者能够创建出功能丰富、交互性强的Web应用程序。本文将深入探讨JavaScript中的API与Web AP…...

比较数据迁移后MySQL数据库和OceanBase数据仓库中的表

设计一个MySQL数据库和OceanBase数据仓库的表数据比较的详细程序流程,两张表是相同的结构,都有整型主键id字段,需要每次从数据库分批取得2000条数据,用于比较,比较操作的同时可以再取2000条数据,等上一次比较完成之后,开始比较,直到比较完所有的数据。比较操作需要比较…...