设计模式解析---------------单例模式

news/2024/5/16 20:04:45/文章来源:https://blog.csdn.net/qq_44920726/article/details/125671456

单例模式定义

确保某一个类只有一个实例,而且自行实例化并向整个系统提供这个实例。

单例模式的使用场景

确保某个类只有一个对象的场景,避免产生多个对象消耗过多的资源,或者某种对象有且只能有一个。

单例模式的UML图

图1
角色介绍:

  • Client --------------- 高层客户端
  • Singleton ----------- 单例类

实现单例模式的要点:

  1. 构造函数不对外开放,一般是 Private;
  2. 通过一个静态方法或者枚举类返回单例类对象;
  3. 确保单例类的对象有且只有一个,尤其是在多线程环境下;
  4. 确保单例类对象在反序列化时不会重新构建对象;

饿汉单例模式

一个公司只有一个CEO,可以有几个VP,无数个员工。

/*
*  普通员工
* */
public class Staff {public void work(){System.out.println("干活");}
}
/*
* 副总裁
* */
public class VP extends Staff{public void work(){System.out.println("管理下面的经理");}
}
/*
* CEO  饿汉单例模式
* */
public class CEO extends Staff{private static final CEO mCeo = new CEO();// 构造函数私有private CEO(){}// 公有的静态函数,对外暴露获取单例对象的接口public static CEO getmCeo(){return mCeo;}public void work(){System.out.println("管理VP");}
}
/*
* 公司类
* */
public class Company {private List<Staff> staffList = new ArrayList<Staff>();public void addStaff(Staff per){staffList.add(per);}public void showAllStaffs(){for (Staff per : staffList){System.out.println("obj : " + per.toString());}}
}

测试类

public class Test {public static void main(String[] args) {Company company = new Company();// CEO 只能通过getCeo函数获取CEO ceo = CEO.getmCeo();CEO ceo1 = CEO.getmCeo();company.addStaff(ceo);company.addStaff(ceo1);// 通过 new 创建vp 对象VP vp = new VP();VP vp1 = new VP();// 通过 new 创建 staff 对象Staff staff = new Staff();Staff staff1 = new Staff();Staff staff2 = new Staff();company.addStaff(vp);company.addStaff(vp1);company.addStaff(staff);company.addStaff(staff1);company.addStaff(staff2);company.showAllStaffs();}
}

运行结果如下图,我们可以发现 CEO 的地址是一样的,说明构建的对象实例是唯一的
在这里插入图片描述

懒汉单例模式

public class Singleton {private static Singleton instance;private Singleton(){}public static synchronized Singleton getInstance(){if(instance == null){instance = new Singleton();}return instance;}
}

上面的代码中增加了一个 synchronized 关键字,也就是 getInstance 是一个同步方法,这是保证在多线程下单例对象唯一性的手段。
懒汉单例模式的优点是单例只有在使用时才会被实例化,在一定程度上节约了资源;
缺点是第一次加载需要及时进行实例化,反应稍慢,最大问题是每次 getInstance 都进行同步,造成不必要的同步开销。

Double Check Lock (DCL) 单例模式

public class Singleton {private static Singleton instance = null;private Singleton(){}public void doSomething(){System.out.println("do.sth.");}public static Singleton getInstance(){if(instance == null){synchronized (Singleton.class){if (instance == null){instance = new Singleton();}}}return instance;}

静态内部类单例模式

/*
*  静态内部类
* */public class Singleton {private Singleton(){}public static Singleton getInstance(){return SingletonHolder.sInstance;}/**  静态内部类* */private static class SingletonHolder{private static final Singleton sInstance = new Singleton();}
}

当第一次加载 Singleton 类时并不会初始化 sInstance ,只有在第一次调用 Singleton 的 getInstance 的方法才会导致 sInstance 被初始化。所以,第一次调用 getInstance 方法会导致虚拟机加载 SingletonHolder 类,这种方式不仅能够确保线程安全,也能保证单例对象的唯一性,同时也延迟了单例的实例化。

枚举单例

public enum SingletonEnum {INSTANCE;public void doSomething(){System.out.println("do.sth.");}
}

枚举单例最大的优点就是简单,枚举在 java 中与普通的类是一样的,不仅能有字段,还能有自己的方法。最重要的是默认枚举实例的创建是线程安全的,并且在任何情况下都是一个单例。

使用容器实现单例模式

public class SingletonManger {private static Map<String,Object> objectMap = new HashMap<String,Object>();private SingletonManger(){}public static void registerService(String key,Object instance){if (!objectMap.containsKey(key)){objectMap.put(key,instance);}}public static Object getService(String key){return objectMap.get(key);}
}

在程序的初始,将多种单例类型注入到一个统一的管理类中,在使用时根据key获取对象对应类型的对象。这种方式可以让我们管理多种类型的单例,并且在使用是通过统一的接口进行获取操作,降低用户的使用成本,也对用户隐藏了具体实现,降低了耦合度。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.luyixian.cn/news_show_395732.aspx

如若内容造成侵权/违法违规/事实不符,请联系dt猫网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

数字媒体概论——系统篇

一&#xff1a;需求分析 需求分析三大要素&#xff1a; 表达内容 -> 媒体种类面向人群 -> 交互方式使用方式 -> 硬件需求 例如&#xff1a;海洋馆需要一个可以展示海洋生物知识的媒体交互系统&#xff0c;可供多人同时观赏&#xff0c;主要面向儿童&#xff0c;这里…

计算机二级C语言题库(44套真题+刷题软件)第一套

刷题软件 gongzhonghao&#xff1a;露露IT 1、循环队列的存储空间为Q(1:100),初始状态为frontrear100。经过一系列正常的入队与退队操作后,frontrear99,则循环队列中的元素个数为( )。 A. 0或100 B. 1 C. 2 D. 99 本题考查知识点是循环队列。当队头和队尾指针指向同一个元素…

常见的图片格式介绍

常见的图片格式介绍 图片&#xff08;Picture&#xff09;包括图形、图像。图形&#xff08;Graph&#xff09;是矢量图&#xff08;Vector Drawn&#xff09;&#xff0c;图像&#xff08;Image&#xff09;是位图&#xff08;Bitmap&#xff09;。 图片&#xff08;Picture…

【老板要我啥都会】|前端升全栈之项目使用express重构项目(下篇)

前言 承接上一篇文章&#xff0c;《前端升全栈之项目使用express重构项目&#xff08;上篇&#xff09;》&#xff0c;我们继续讲解下一篇的项目使用express重构项目完整的下一篇&#xff08;主要是国庆&#xff0c;需要放松&#xff0c;所以该文章分为上下篇&#xff0c;请大…

2022年Webpack 5初学者完整指南

2022年Webpack 5初学者完整指南 从基础到高级学习 Webpack 5&#xff01;将 Webpack 与 JS、CSS、NPM、模块联合和微前端一起使用 课程英文名&#xff1a;Webpack 5 in 2022 The Complete Guide For Beginners 此视频教程共2.5小时&#xff0c;中英双语字幕&#xff0c;画质…

都这麽大了还不快了解防病毒网关?

目录 一、思考 二、实验 1、实验拓扑 2、配置过程&#xff08;网页端配置&#xff09; 三、总结 1. 什么是恶意软件&#xff1f; 2. 恶意软件有哪些特征&#xff1f; 3. 恶意软件的可分为那几类&#xff1f; 4. 恶意软件的免杀技术有哪些&#xff1f; 5. 反病毒技术…

OceanBase 从0到1数据库内核实战教程学习笔记 - 3.OceanBase基础架构和开发技巧

这篇文章主要介绍王泽林老师分享的 《OceanBase 的基础架构和开发技巧》。如果您看过第一篇文章的对应视频&#xff0c;会发现整个系列主要分为 MiniOB 和 OceanBase 两个系列&#xff0c;本篇文章就是 OceanBase 系列的开篇&#xff0c;所以文章中会有很多 OceanBase 的概念和…

Java类的成员方法的创建以及调用|在使用时有何意义|附运行方式及题目

&#x1f51d;&#x1f51d;&#x1f51d;&#x1f51d;&#x1f51d;&#x1f51d;&#x1f51d;&#x1f51d;&#x1f51d;&#x1f51d;&#x1f51d;&#x1f51d;&#x1f51d;&#x1f51d;&#x1f51d; &#x1f947;博主昵称&#xff1a;Jovy. &#x1f35f;博客主页…

遥感航拍影像25篇CVPR39个数据集

摘要 本文讲解了39个数据集&#xff0c;关于高空卫星图和低空无人机航拍图像。 本文汇总了25篇CVPR2020年和2021年的论文。 本文详细介绍了这25篇论文的任务是什么&#xff0c;难点是什么&#xff0c;场景是什么。 同时&#xff0c;本文在需要的地方解释了一些卫星图和航拍…

Vue学习第35天——模拟项目上线基本流程

一、打包 将.vue文件生成为.html、.css、.js文件 npm run build执行完之后&#xff0c;会在项目中生成一个dist文件&#xff08;执行的速度取决于项目的大小以及电脑的配置&#xff09; 二、创建服务器 没有后端服务器&#xff0c;这里我们使用node.js express 搭建一个服…

(附源码)计算机毕业设计ssm餐厅管理系统

毕设帮助&#xff0c;指导&#xff0c;本源码分享&#xff0c;调试部署(见文末) 4.1.2系统的主要的功能结构 餐厅管理系统的主要功能的结构如图4-1所示。 图4-1系统功能结构图 4.2系统设计 4.2.1数据表E-R图 菜谱信息属性图如图4-2所示。 图4-2菜谱信息实体属性图 账单信息…

3、数据类型中的数据位置,stograge、memory、calldata

数据位置 所有的复杂类型,即 数组 和 结构 类型,都有一个额外属性,“数据位置”,说明数据是保存在 内存memory 中还是 存储storage 中。 根据上下文不同,大多数时候数据有默认的位置,但也可以通过在类型名后增加关键字 storage 或 memory 进行修改。 函数参数(包括返回的…

Day11 栈和队列

150. 逆波兰表达式求值 解法一&#xff1a;将计算部分抽象成一个函数&#xff0c;使代码更加简洁&#xff0c;避免了很多冗余操作。对比下面解法二&#xff08;我自己写的&#xff09;&#xff0c;此解法&#xff08;参考别人的&#xff09;的代码更加精简。核心思想都是利用栈…

Linux学习 -- Shell面试题练习

1、使用Linux命令查询file1中空行所在的行号 awk /^$/ {print NR} file1 // 使用正则表达式^$ 来表示空行 2、使用Linux命令计算文件a.txt的第二列的和并输出 张三 40 李四 50 王五20 cat a.txt | awk -F " " {sum$2} END {print sum} 3、Shell脚本中如何检查一个文…

欧拉函数的power

在算数基本定理中有 $ N = p_{1}^{a1} p_{2}^{a2} p_{3}^{a3} ..... p_{k}^{ak} $ wuw在y总的课中是用了容斥原理进行推导得到了 $ \phi(x) = N * (1 - \frac{1}{p1}) * (1 - \frac{1}{p2}) * .... * ( 1 - \frac{1}{pk}) $ 所以就可以得到依靠该公式得出的欧拉公式的算法 #in…

基本语法

输入输出输入: 输出:字符串: System.out.println("hello world!"); 字符串+数值 System.out.println("a =" + 8);import java.util.Scanner; //Scanner 是一个简单的文本扫描器public class MyInput {public static void main(String[] Args) {Scanne…

cat笔记

0.学习目标 能够知道什么是CAT能够搭建CAT服务端环境能够进行CAT客户端的集成能够使用CAT监控界面进行服务监控能够完成CAT和常用框架集成了解CAT告警配置了解CAT客户端和服务端原理 1.CAT入门 在这一部分我们主要介绍以下3部分内容&#xff1a; 什么是调用链监控 什么是CA…

【虚幻引擎UE】UE5 阴影异常与优化解决方案合集

一、消除阴影锯齿 异常效果&#xff1a; 模型锯齿状阴影。 解决方案&#xff1a; ① 确定打开虚拟阴影贴图。 虚拟阴影贴图&#xff08;VSM&#xff09;是一种全新的阴影贴图方法&#xff0c;可以提供稳定的高分辨率阴影。通过与虚幻引擎5的Nanite虚拟几何体、Lumen全局光照和…

Seata安装

文章目录一、下载二、MySQL配置三、Nacos配置四、启动参考一、下载 从Seata下载地址下载 https://github.com/seata/seata/releases 这里下载的是seata-server-1.5.2.tar.gz 解压&#xff1a; tar -xvf seata-server-1.5.2.tar.gz修改配置&#xff1a;conf/application.ym…

Python实战——全球疫情数据采集, 并做可视化

前言 大家早好、午好、晚好吖~ 知识点: 爬虫基本流程 requests 发送请求 re 正则表达式 json 结构化数据解析 开发环境: python 3.8: 解释器 pycharm: 代码编辑器 requests 发送请求 pyecharts 绘制图表 pandas 读取数据 基本原理: 模拟成 浏览器/客户端 向 服务器…