详解23种设计模式——单例模式

news2024/11/24 16:01:35

单例模式 | CoderMast编程桅杆单例模式 单例模式是最常用的设计模式之一,他可以保证在整个应用中,某个类只存在一个实例化对象,即全局使用到该类的只有一个对象,这种模式在需要限制某些类的实例数量时非常有用,通常全局只需要一个该对象即可,如一些配置文件映射对象、数据库连接对象等。 饿汉模式 和 懒汉模式 单例模式根据其实现方式不同,又可以分成两种类型:饿汉模式 和 懒汉模式。 饿汉模式:...icon-default.png?t=N7T8https://www.codermast.com/dev-idea/design-patterns/create-patterns/singleton-pattern.html

单例模式是最常用的设计模式之一,他可以保证在整个应用中,某个类只存在一个实例化对象,即全局使用到该类的只有一个对象,这种模式在需要限制某些类的实例数量时非常有用,通常全局只需要一个该对象即可,如一些配置文件映射对象、数据库连接对象等。

饿汉模式 和 懒汉模式

单例模式根据其实现方式不同,又可以分成两种类型:饿汉模式 和 懒汉模式。

  • 饿汉模式:可以理解为餐馆老板认为每个顾客来到餐馆时都是快要饿死的状态,一旦请求食物,则必须立刻提供给他,必须尽快让他吃到东西,为了达到这样的效果,就必须提前把食物准备好,只等顾客来吃即可。

  • 懒汉模式:可以理解为餐馆老板是一个非常懒的人,没有客人的时候,他什么也不会准备,只有当顾客点餐以后,老板才会开始工作。

设计思想

  1. 日志记录

在应用程序中,通常会有多个模块需要记录日志,为了避免创建多个日志记录器实例,使用单例模式就可以确保只有一个日志记录器实例,从而避免重复记录日志并提高应用程序的性能。

  1. 数据库连接

在应用程序中,需要频繁的和数据库进行交互,使用单例模式可以确保只有一个数据库连接实例,从而减少数据库连接的数量,提高程序的性能,减少资源的消耗。

  1. 配置文件

在应用程序中,通常会有一些全局的配置参数,如数据连接信息、项目配置信息、缓存大小等一些参数,使用单例模式可以确保只有一个配置实例,保证了参数的唯一性,从而方便管理和修改配置参数。

实现案例

饿汉模式

这种模式下,即使当前没有人来请求资源,在类加载的时候就会提前将所需要的资源准备好,只等来拿。

因为是在类加载的阶段初始化的,且类加载在程序的执行过程中仅出现一次,故其是线程安全的。

class SingletonHungry {
    // static 修饰的,在类加载时就会被初始化
    private static final SingletonHungry singletonHungry = new SingletonHungry();

    // 将构造器设为私有的,禁止从外部创建实例
    private SingletonHungry() {

    }

    // 提供获取单例对象的方法
    public static SingletonHungry getInstance() {
        return singletonHungry;
    }
}

懒汉模式

这种模式下,只有当有人来获取资源的时候,才会开始准备资源。因为是需要进行手动初始化,在并发环境下就有可能出现构建了多个实例对象的情况,需要我们手动去处理。

  • 懒汉模式:不考虑并发

class SingletonLazy {
    // 默认不初始化
    private static SingletonLazy singletonLazy;

    // 将构造器设为私有的,禁止从外部创建实例
    private SingletonLazy() {

    }

    // 提供获取单例对象的方法
    public static SingletonLazy getInstance() {
        if (singletonLazy == null) {
            singletonLazy = new SingletonLazy();
        }

        return singletonLazy;
    }
}
  • 懒汉模式:考虑并发

使用双重检查锁它可以在保证线程安全的同时实现延迟加载

class SingletonLazy {
    // 默认不初始化
    private static SingletonLazy singletonLazy;

    // 将构造器设为私有的,禁止从外部创建实例
    private SingletonLazy() {

    }

    // 提供获取单例对象的方法
    public static SingletonLazy getInstance() {
        if (singletonLazy == null) {
            synchronized ( SingletonLazy.class ) {
                if (singletonLazy == null) {
                    singletonLazy = new SingletonLazy();
                }
            }
        }

        return singletonLazy;
    }
}

枚举方式

警告

前面的两种方式中,看似是实现了单例模式,但是 Java 中一些机制可以破坏单例模式,会导致单例对象不唯一,例如反射机制、克隆机制、序列化和反序列化等。那这该如何解决呢?答案是使用 Enum 类来实现。

使用枚举实现单例模式的好处是,可以避免反射和序列化攻击。因为枚举类型的构造函数是私有的,所以无法使用反射来创建实例;而且枚举类型的实例在序列化和反序列化时会自动处理好,所以也无法通过序列化和反序列化来破坏单例。

  • 定义枚举类

public enum SingletonEnum {
    SINGLETONENUM;

    public void doSomething() {
        // TODO:这里可以写一些单例对象的相关行为和操作
    }
}
  • 使用枚举类

public class SingletonEnumTest {
    public static void main(String[] args) {
        SingletonEnum singletonEnum = SingletonEnum.SINGLETON_ENUM;
        SingletonEnum singletonEnum2 = SingletonEnum.SINGLETON_ENUM;

        System.out.println(singletonEnum  == singletonEnum2);
    }
}

输出的结果为 true ,说明这两个是同一个对象。

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

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

不使用加减运算符实现整数加和减

文章目录 进位 进位 加粗 最近想出了不适用运算符实现加与减 首先按位与找出的是需不需要进位 按位与是两边同时为1,则为1,那么如果两边同时为1的话,是不是就该进位?所以我们用按位与来判断是否需要进位 然后再按位异或找出不同的位数 按位异或是两边不相等,也就是1 和 0的时…

LAPGAN浅析

LAPGAN 引言 在原始 GAN和CGAN中,还只能生成 16*16, 28*28, 32*32 这种低像素小尺寸的图片。而LAPGAN首次实现 64*64 的图像生成。与其一下子生成这么大的图像 (包含信息量这么多),不如一步步由小到大,这样每一步生成…

【产品经理修炼之道】- B端产品经理之业务系统设计

很多时候,业务系统建设好坏决定了企业的核心竞争力。作为产品经理,如何建设好业务系统这种OLTP类产品?本文从梳理业务流程、参与业务调研和设计业务系统三个步骤,教大家如何做好业务系统建设。 很多人都说设计B端产品最重要的是搞…

线性代数:抽象向量空间

一、说明 有些函数系列极具线性代数的向量特征。这里谈及多项式构成函数的线性代数意义。问题是这个主题能展开多少内涵?请看本文的论述。 二、线性空间和向量 让我先问你一个简单的问题。什么是向量?为了方便起见,二维箭头从根本上说是平…

【UE 材质】水波纹效果

效果 模拟雨水打落在水面上的效果 步骤 1. 下载所需纹理和纹理 纹理2. 新建一个材质,这里命名为“M_WaterRipples” 打开“M_WaterRipples”,添加一个纹理采样节点,纹理使用第一步下载的纹理 将纹理采样节点的R通道连接到基础颜色&#x…

04_Scala网络序列化

文章目录 **1.网络****2. 序列化** 1.网络 Scala进行网络数据交互,使用是Java的IO类 实现案例:客户端连接服务器,向服务器发送数据; 1.创建两个文件,CLIENT,Server obj类型** ** Server端 2.在Server端…

2024中国航空航天暨无人机展诚邀全国相关商协会组团参展

2024中国航空航天暨无人机展诚邀全国相关商协会组团参展 2024中国航空航天暨无人机展览会诚邀全国各关联商会、协会,联盟、各专业会展公司、各级城市政府及关联产业园区、各关联网站报纸杂志及平台等组团参展 主办单位: 中国航空学会 重庆市南岸区人民…

OpenHarmony ArkUI 实战开发—ETS 装饰器解读

前言 最近利用空闲时间在学习华为方舟开发框架(简称:ArkUI)的ets开发,发现在ets语言中装饰器的有着非常重要的作用,在写每一个自定义组件时都需要用到它,看到装饰器这个字眼,想起之前学过的设计…

偏见将如何扼杀你的人工智能/机器学习策略以及如何应对

任何类型的模型中的“偏差”都描述了模型对提示或输入数据的响应不准确的情况,因为它没有接受足够的高质量、多样化的数据训练来提供准确的响应。一个例子是 苹果的面部识别手机解锁功能对于肤色较深的人来说失败率明显高于肤色较浅的人。 该模型没有接受过足够多的…

分享8款安全监控/日志记录工具

安全监控工具的作用是实时监控和分析系统的安全状态,而日志记录工具的作用主要是记录系统的运行过程及异常信息。 关于安全监控工具,它通过对计算机系统、网络、应用程序和数据进行实时监控和分析,帮助发现和防止安全威胁和攻击。这种监控不…

2024全网最火的接口自动化测试,一看就会

🔥 交流讨论:欢迎加入我们一起学习! 🔥 资源分享:耗时200小时精选的「软件测试」资料包 🔥 教程推荐:火遍全网的《软件测试》教程 📢欢迎点赞 👍 收藏 ⭐留言 &#x1…

2024信息系统、信号处理与通信技术国际会议(ICISPCT2024)

2024信息系统、信号处理与通信技术国际会议(ICISPCT2024) 会议简介 2024国际信息系统、信号处理与通信技术大会(ICISPCT2024)将在青岛隆重开幕。本次会议旨在汇聚全球信息系统、信号处理和通信技术领域的专家学者,共同探索行业…

全网最全的接口测试教程

🍅 视频学习:文末有免费的配套视频可观看 🍅 关注公众号【互联网杂货铺】,回复 1 ,免费获取软件测试全套资料,资料在手,涨薪更快 其实我觉得接口测试很简单,比一般的功能测试还简单&…

组合模式【结构型模式C++】

1.概述 组合模式又叫部分整体模式属于结构型模式,是用于把一组相似的对象当作一个单一的对象。组合模式依据树形结构来组合对象,用来表示部分以及整体层次。 2.结构 组件(Component):定义了组合中所有对象的通用接口&#xff0c…

信号的调幅(AM)、调频(FM)与调相(PM)对频谱结构的影响(找找复刻电赛D题的伙伴)

0.目录 (1)调制与解调的基本概念 (2)调幅对频谱结构的影响 (3)调频信号幅值变化对频谱结构的影响 (4)调频信号频率变化对频谱结构的影响 (5)调幅调频信号…

Java Web 网页设计(3)

3.servlet JavaWeb——Servlet(全网最详细教程包括Servlet源码分析)-CSDN博客 servlet java不支持 只有Tomcat支持 使用时添加一下 servlet中最常用的两个(固定)方法: 下面我们创建一个servlet类 package com.oracle…

PE文件(三)节表

节表引入 PE文件的结构是由DOS头PE标记标准PE头可选PE头节表多个节构成的,如下便是一个pe文件结构图,它的每一段都可以被称作节 图中这么多的节在硬盘上和内存中的存储位置都由节表去管理和记录,而不是随意的存储。 节表相当于是一个对各个…

论文解读:Label Hallucination for Few-Shot Classification

文章汇总 动机 本文的一个思想就是:尽管新类的标签并不能“恰如其分”地表示基数据集中的样本,但是很多基数据集的样本会包含与新类中相似的对象,例如,基数据集中的老虎和新类中的猫有相似的特征,那么就有60%的概率将…

补充centos7软件包的方式/编译安装源码包软件/企业案例/linux进程管理/企业管理进程系列命令(企业经验)--8820字详谈

cenros7软件包的安装方式 软件包分类安装方式优缺点rpm包软件开发商编译打包,安装简单,快速软件版本可能偏低,安装路径是固定好的源码包自己手动编译安装并且复杂软件爸爸随意选,可以定制安装路径二进制包解压就可以使用不能进行…

new String和直接赋值的一些问题

分析1 我们先看以下代码: String str1 "abc"; // 在常量池中String str2 new String("abc"); // 在堆上System.out.println(str1 str2)以上结果的输出是什么? 输出:false 前置知识: 在JVM中&#xff0c…