23天读懂23种设计模式:单例模式(创建型)

485芯片AB波形正负半周的问题探讨       本人做的一个产品,产品的其中一个接口是RS485的,我们使用的芯片是MAX13487E。MCU是STM32F103,MCU的USART通过光耦隔离后,接到MAX13487E。因为STM32F103的VCC是3.3V的,MAX13487E的VCC是5V。      部分原理图如下,上述部分电路参考了官方的参考设计,现在测试的AB波形时候发现如下问题。1.把R10和R16改为1k,示波器C... 阅读详情

点击上方 蓝字 关注我们

创建型模式是用来创建对象的模式,抽象了实例化的过程,帮助一个系统独立于其他关联对象的创建、组合和表示方式。

单例模式目的:保证一个类仅有一个实例,并提供一个访问它的全局访问点。

winter

单例模式也是创建型的设计模式之一,本文是设计模式系列(共24节)的第2篇文章。

设计模式是基于六大设计原则进行的经验总结:《第一节:设计模式的六大原则》

创建型设计模式共5种:

  • 单例模式(Singleton Pattern):一个类只有一个实例,而且自行实例化并向整个系统提供这个实例。

  • 工厂方法模式(Factory Pattern):在工厂方法模式中,工厂类成为了抽象类,实际的创建工作将由其具体子类来完成。

  • 抽象工厂模式(Abstract Factory):抽象工厂可以向客户提供一个接口,创建多个产品族中的产品对象,强调的是“对象系列”的变化。

  • 建造者模式(Builder Pattern):把构造对象实例的逻辑移到了类的内部,在类的外部定义了该类的构造逻辑,强调的是产品的构造过程。

  • 原型模式(Prototype Pattern):原型模式和工厂模式一样,同样对客户隐藏了对象创建工作具体的实现细节,通过复制一个现有的对象生成新对象。

单例模式是什么

单例模式(Singleton Pattern)可以说是整个设计中最简单的模式之一,且这种模式即使在没有看设计模式相关资料也经常在编码开发中。

因为在编程开发中经常会遇到这样一种场景,那就是需要保证一个类只有一个实例哪怕多线程同时访问,并需要提供一个全局访问此实例的点。

综上以及我们平常的开发中,可以总结一条经验,单例模式主要解决的是,一个全局使用的类频繁的创建和消费,从而提升提升整体的代码的性能。

普通模式(非线程安全)

普通模式的特点是:不允许外部直接创建,且对象是全局共享。

下面 例子1 是普通实现方法的单例模式,也是我们最常用的:

/**
 * 普通写法
 */
public class SingletonCase1 {
  private static SingletonCase1 singleton = null;
  public SingletonCase1() {
  }
  /**
   * 并发下会产生多个实例
   */
  public static SingletonCase1 getInstance(){
    if (singleton == null){
      singleton = new SingletonCase1();
    }
    return singleton;
  }
}

代码分析:

因此虽然在默认的构造函数上添加了私有属性private,也确实满足了懒加载,但是如果有多个访问者同时去获取对象实例,你可以想象很多人在抢厕所,就会造成多个同样的实例并存,所以是非线程安全的。

饿汉模式(线程安全)

饿汉式单例模式的特点是:类在加载时就直接初始化了实例。即使没用到,也会实例化,因此,它也是线程安全的单例模式。

下面 例子2 是饿汉模式:

/**
 * 饿汉式
 * 饿汉式的特点是:类在加载时就直接初始化了实例。即使没用到,也会实例化,因此,也是线程安全的单例模式。
 */
public class SingletonCase3 {
  /**类在加载的时候直接进行初始化*/
  private static SingletonCase3 singleton = new SingletonCase3();
  public SingletonCase3() {
  }
  /**
   * 对外暴露唯一接口
   * 提供单例对象
   */
  public static SingletonCase3 getInstance(){
    return singleton;
  }
}

懒汉模式(加锁&线程安全)

懒汉式单例模式的特点:对比普通模式,给方法加了排它锁,这是线程安全的写法;对比饿汉模式,全局对象只会在用到时才会进行初始化。

下面 例子3 是懒汉模式:

/**
 * 懒汉式,对比SingletonCase1,给方法加了排它锁,这是线程安全的写法。
 * 用到这个实例时才去调用方法实例化。但是,我们把整个方法都同步了,效率很低下,我们可以继续优化,只在创建实例的地方加上同步
 */
public class SingletonCase2 {
  private static SingletonCase2 singleton = null;
  public SingletonCase2() {
  }
  /**
   * 整个方法锁住了,效率较低
   * @return
   */
  public synchronized static SingletonCase2 getInstance(){
    if (singleton == null){
      singleton = new SingletonCase2();
    }
    return singleton;
  }
}

双重校验模式

双重校验模式的特点:考虑到多线程下的并发操作,全局对象使用了 volatile关键字 修饰,同时在对象初始化时进行加锁防止对象被其他线程重复创建。

此处可以参考《Java并发编程实战》的 第3章volatile的使用。

下面 例子4 是双重校验模式:

/**
 * 双重非空判断,new对象前加一次锁。
 * volatile关键字,考虑的是,new关键字在虚拟机中执行时其实分为很多步骤,具体原因可以参考深入理解java虚拟机一书(考虑的是这个new关键字字节码执行时是非原子性的),而volatile关键字可以防止指令重排。
 */


public class SingletonCase4 {


  /**volatile防止指令重排*/
  private static volatile SingletonCase4 singleton;


  public SingletonCase4() {
  }


  /**
   * 只是在实例为空时才进行同步创建
   * 为什么做了2次判断?
   * A线程和B线程同时进入同步方法 getInstance
   * 然后都在1位置处判断了实例为null
   * 然后都进入了同步块2中
   * 然后A线程优先进入了同步代码块2中(B线程也进入了),然后创建了实例
   * 此时,如果没有3处的判断,那么A线程创建实例同时,B线程也会创建一个实例
   * 所以,还需要做2次判断
   * */
  public static SingletonCase4 getInstance(){
    if (singleton == null){
      synchronized (SingletonCase4.class){
        if (singleton == null){
          singleton = new SingletonCase4();
        }
      }
    }
    return singleton;
  }
}

内部类模式

内部类模式的特点是:由于静态内部类跟外部类是平级的,所以外部类加载的时候不会影响内部类,因此实现了懒加载。

下面 例子5 是内部类模式:

/**
 * 内部类
 * 优点:由于静态内部类跟外部类是平级的,所以外部类加载的时候不会影响内部类,因此实现了lazy loading, 同时也是利用静态变量的方式,
 * 使得INSTANCE只会在SingletonHolder加载的时候初始化一次,从而保证不会有多线程初始化的情况,因此也是线程安全的。
 */
public class SingletonCase5 {
  //静态内部类,懒加载:在被用到时才加载(根据内部类不会在其外部类被加载的同时被加载的事实)
  private static class SingletonCase5Holder{
    private static final SingletonCase5 singleton = new SingletonCase5();
  }
  public SingletonCase5() {
  }
  public static SingletonCase5 getInstance(){
    return SingletonCase5Holder.singleton;
  }
}

枚举类模式

枚举类模式的特点是:创建一个枚举类,封装一个对象,通过枚举类的私有构造器,强化了单例模式,且实现了懒加载,当唯一全局入口被调用才会初始化对象。

此处可以参考《Effective Java》的 第3点 以及 第4点。

下面 例子6 枚举类模式:

/**
 * 枚举类
 * 本质就是:创建一个枚举类,封装一个对象,枚举类私有构造器中初始化对象
 */


public class SingletonCase6 {
  enum SingletonEnum {
    //懒加载,创建一个枚举对象,该对象天生为单例
    INSTANCE;
    private SingletonCase6 singleton;


    //私有化枚举的构造函数(强调不可外部实例化)
    private SingletonEnum() {
      singleton = new SingletonCase6();
    }


    public SingletonCase6 getSingleton() {
      return singleton;
    }
  }


  private SingletonCase6() {
  }


  public static SingletonCase6 getInstance(){


    getInstance();
  }
}

通过私有化构造器可以强化单例属性。

总结

单例模式应该是最常见的设计模式之一了,它归类在设计模式创建型模式,用于解决对象创建的对象复用问题。

创建型模式还包括:原型模式、工厂模式、抽象工厂模式和建造者模式,待后续我们再细细解读。

往期推荐

《源码系列》

《JDK之Object 类》

《JDK之BigDecimal 类》

《JDK之String 类》

《JDK之Lambda表达式》

《经典书籍》

《Java并发编程实战:第1章 多线程安全性与风险》

《Java并发编程实战:第2章 影响线程安全性的原子性和加锁机制》

《Java并发编程实战:第3章 助于线程安全的三剑客:final & volatile & 线程封闭》

《服务端技术栈》

《Docker 核心设计理念》

《Kafka史上最强原理总结》

《HTTP的前世今生》

《算法系列》

《读懂排序算法(一):冒泡&直接插入&选择比较》

《读懂排序算法(二):希尔排序算法》

《读懂排序算法(三):堆排序算法》

《读懂排序算法(四):归并算法》

《读懂排序算法(五):快速排序算法》

《读懂排序算法(六):二分查找算法》

《设计模式》

《设计模式之六大设计原则》

扫描二维码

获取技术干货

后台技术汇

点个“在看”表示朕

已阅

Jetson编译安装pycuda 可使用nvcc --version查看是否有信息输出,若没有,且安装cuda的情况下,需要手动将CUDA 的路径添加到环境变量中。编译生成_pvt_struct.cpython-38-aarch64-linux-gnu.so文件。基于jetson orin nano jetpack512模块上安装pycuda。4、获取pycuda源码(版本根据实际情况获取)2、进入conda环境并安装cuda工具包。9、若未检测出来需要清除并强制编译。7、编译成功后安装pycuda。5、配置编译并设置环境变量。 阅读详情

相关推荐

国内开发者福音:手把手教你用微软Authenticator搞定GitHub 2FA验证(附Recovery Codes保存指南)

本文详细介绍了国内开发者如何使用微软Authenticator中国版轻松配置GitHub双重身份验证(2FA),解决短信验证不可用和国际验证器访问困难的问题。重点强调了恢复码(Recovery Codes)的安全备份策略,确保账户安全无忧。

weixin_28840143的博客 435

23种设计模式(通俗易懂,白话翻译)

创建型模式 1、FACTORY—追MM少不了请吃饭了,麦当劳的鸡翅和肯德基的鸡翅都是MM爱吃的东西,虽然口味有所不同,但不管你带MM去麦当劳或肯德基,只管向服务员说“来四个鸡翅”就行了。麦当劳和肯德基就是生产鸡翅的Factory 工厂模式:客户类和工厂类分开。消费者任何时候需要某种产品,只需向工厂请求即可。消费者无须修改就可以接纳新产品。缺点是当产品修改时,工厂类也要做相应的修改。如:如何创建及如...

SmallTenMr的博客 2705

西门子S7-200 SMART与施耐德ATV变频器Modbus通讯实战:从接线到稳定运行的完整指南

本文详细介绍了西门子S7-200 SMART PLC与施耐德ATV变频器之间实现稳定Modbus通讯的完整实战指南。内容涵盖从硬件接线、参数配置、PLC程序编写到触摸屏设计的全流程,并分享了提升通讯稳定性的关键技巧和常见故障排查方法,助力工业自动化系统可靠运行。

kkk56的博客 1106

【设计模式】创建型模式(抽象工厂、建造者、原型、单例

文章目录1.抽象工厂模式2.建造者模式3.原型模式4.单例模式 开始之前,先简单了解下UML类图的几种关系。PS:组合关系是在内部实例化指向对象,为保持部分与整体的生命周期一致。 1.抽象工厂模式 //Client DBFactory factory = new OracalFactory(); Connnection connection = factory.createConnection(); ... 说明: 抽象工厂模式是所有工厂模式的一般形式; 工厂方法模式(产品等级结构只有一个,即只有一个抽象

qq_40265247的博客 368

Zephyr,设备树概述

Zephyr使用设备树(DTS)描述硬件配置,通过设备树源码和绑定文件生成C头文件供开发使用。设备树采用树状结构,节点对应硬件设备,属性描述硬件特性。示例展示了I2C总线及其外设的节点层级关系,包括单元地址、兼容性标识等关键属性。构建系统将设备树转换为devicetree.h中的宏,使开发者能通过DT_前缀宏访问硬件信息,同时保留Kconfig覆盖默认值的能力。

汽车电子软件领域知识分享 722

Mongodb操作与Java(四)MongoTemplate的使用

MongoTemplate的使用

A乐神的博客 3437

23 种设计模式详解(全23种)

设计模式

雨中深巷的油纸伞 12万+

3U 与 SV630A 伺服实现 CANLINK 通讯

SD410这组参数特别重要,这个32位特别重要,是防止数值乱码的关键。

weixin_42714122的博客 2694

23天读懂23种设计模式:原型模式(创建型)

点击上方 蓝字 关注我们创建型模式是用来创建对象的模式,抽象了实例化的过程,帮助一个系统独立于其他关联对象的创建、组合和表示方式。原型模式目的:用原型实例指定创建对象的种类,并且通过拷贝...

Diligence is the mother of success. 283

从零到一:YOLOv11高帧率模型在RDK X5上的ONNX转换与部署实战

本文详细介绍了将最新的YOLOv11高帧率模型部署到地平线RDK X5开发板的完整实战流程。内容涵盖从PyTorch模型导出ONNX、地平线工具链环境配置与模型量化编译,到编写高效的板端推理代码,并针对高帧率目标进行了后处理优化。通过实战避坑指南,帮助开发者在RDK X5上实现30FPS以上的实时目标检测。

weixin_29089057的博客 139

Playwright爬虫实战:破解动态网页懒加载与无限滚动

本文介绍了使用Playwright处理懒加载和无限滚动页面的完整解决方案。摘要如下: 问题分析:传统爬虫无法获取JS动态渲染内容,Playwright能模拟真实浏览器行为解决此类问题。 核心原理: 懒加载:资源延迟加载,滚动触发 无限滚动:滚动到底部异步加载新内容 技术方案: 分段滚动页面并等待加载 动态监测页面高度变化 合理设置等待和终止条件 代码实现: 提供图片懒加载和无限滚动列表的完整可运行代码 包含异常处理和性能优化建议 关键优势: 比传统爬虫更可靠 支持复杂交互场景 完善的错误处理机制 该方法已在

专注于Python爬虫开发,分享爬虫技巧、项目实战与反爬经验,使用Scrapy、BeautifulSoup等工具,解决数据抓取难题。 523

设计模式|创建型模式

目录 前言 读懂UML图 设计模式六大原则 创建型模式原则 创建型模式 分析 1.简单工厂模式 2.工厂方法模式 3.抽象工厂方法模式 4.建造者模式 5.单例模式 创建型模式 总结 前言 设计模式是一套被反复使用、多数人知晓的、经过分类编目的、代码设计经验的总结,设计模式不是具体的代码,而是一种合理、易拓展、易维护的代码架构思想。设计模式被运用在各种优秀的框架中。掌握设...

leo187的博客 2422

IDEA的使用指南

IDEA基于java的使用手册,可以最快速的上手,在使用中不断的丰富自己的使用技巧.

23天读懂23种设计模式:建造者模式(创建型)

点击上方 蓝字 关注我们创建型模式是用来创建对象的模式,抽象了实例化的过程,帮助一个系统独立于其他关联对象的创建、组合和表示方式。建造者模式目的:将一个复杂的构建与其表示相分离,使得同样...

Diligence is the mother of success. 248

LinePhone3.2.7(android端最新版本) sip客户端

SIP客户端For android:LinePhone3.2.7(最新版本),官网地址:http://www.linphone.org/

ssm框架搭建

这个是一个在idea上成功跑起来的ssm框架项目,保存在这里方便以后使用直接下载

23天读懂23种设计模式:工厂方法模式(创建型)

点击上方 蓝字 关注我们创建型模式是用来创建对象的模式,抽象了实例化的过程,帮助一个系统独立于其他关联对象的创建、组合和表示方式。工厂方法模式目的:封装构造对象具体过程,解耦客户端与构造...

Diligence is the mother of success. 275

pscad IEEE标准系统搭建说明

pscad IEEE标准系统搭建说明,包含典型的IEEE 9节点、14节点、30节点、39节点和118节点系统。内含标准测试系统的原始数据和潮流结果。

23天读懂23种设计模式:抽象工厂设计模式(创建型)

点击上方 蓝字 关注我们创建型模式是用来创建对象的模式,抽象了实例化的过程,帮助一个系统独立于其他关联对象的创建、组合和表示方式。抽象工厂模式的目的:提供一个创建一系列相关或相互依赖对象的...

Diligence is the mother of success. 238

一文读懂设计模式

设计模式(Design Pattern)是一套被反复使用、多数知晓、分类编目、代码设计经验的总结。使用设计模式可提高代码的简洁、易读和可维护性,让代码易于被他人理解且保证软件的可靠性。毫无疑问,设计模式于己于他人于系统都是多赢的;设计模式使代码编写真正工程化;设计模式是软件工程的基石脉络,如同大厦的结构一样。设计模式这个术语是由 Erich Gamma 等人在 20 世纪 90 年代从建筑设计领域引入的,它是对软件设计领域普遍存在的各种问题所提出的解决方案,不涉及完成应用程序的具体的类或对象。

Doublelv 的博客专栏。 1115

全面了解23种设计模式,细说那些被人所知的设计思想。(一周彻底撸完被23种设计模式疯狂折磨)

一,23种设计模式分为三大类别模式 : 1,创建型模式: 它的主要特点是“将对象的创建与使用分离”。这样可以降低系统的耦合度,使用者不需要关注对象的创建细节,对象的创建由相关的工厂来完成。就像我们去商场购买商品时,不需要知道商品是怎么生产出来一样,因为它们由专门的厂商生产。 2,结构型模式: 它的主要特点是 如何将类或对象按某种布局组成更大的结构。它分为类结构型模式和对象结构型模式,前者采用继承机制来组织接口和类,后者釆用组合或聚合来组合对象。由于组合关系或聚合关系比继承关系耦合度低,满足“合成复用原

Crazy_Cw的博客 2403

Java 23 种设计模式:从踩坑到精通 —— 开篇及系列介绍

摘要:本文是《Java 23种设计模式:从踩坑到精通》系列的总入口与导航页。文章梳理了设计模式的起源与三大分类,结合SOLID六大原则,详解为什么2026年设计模式依然重要。提供25篇完整目录、面试高频Top10速记、场景速查索引、易混模式对比表及分级阅读路线,可作为长期收藏的设计模式学习手册。

折哥|智能物流与Java实战,副高数据库工程师。深耕出版社物流WMS/OMS(线体/立库/VGA),也分享Java进阶与OMS电商对接。Oracle→PG实战派。相信沉淀可迁移能力,分享通用技术,不藏不虚。 3580

Python的23种设计模式

设计模式是面对各种问题进行提炼和抽象而形成的解决方案。这些设计方案是前人不断试验,考虑了封装性、复用性、效率、可修改、可移植等各种因素的高度总结。它不限于一种特定的语言,它是一种解决问题的思想和方法。

malingyu的专栏 1226

23种设计模式

一个月学完23种设计模式

qq_36949403的博客 1419

经典伴读_GOF设计模式_创建型模式

上面介绍过的简单工厂模式和工厂方法模式都可以生产多产品,但这有个前提需要生产的商品需要实现同一个Prodcut接口,可以理解为必须为同类型商品。如衣服有多种,T恤、夹克,毛衣,短袖等。那么如果要生产的是整套的产品,如校服不仅有衣服,还有裤子,裙子。电脑不仅有主机,还有显示器,键盘。没错,这里可能不止一个产品接口。当需要创建的是整套产品时需要使用抽象工厂模式。提供一个创建一系列相关或相互依赖对象的接口,而无需指定它们具体的类。//三类产品interfaceShirt{............

逆水行舟,不进则退 638

Python的23种设计模式(完整版带源码实例)

设计模式是面对各种问题进行提炼和抽象而形成的解决方案。这些设计方案是前人不断试验,考虑了封装性、复用性、效率、可修改、可移植等各种因素的高度总结。它不限于一种特定的语言,它是一种解决问题的思想和方法最后的最后由本人水平所限,难免有错误以及不足之处, 屏幕前的靓仔靓女们 如有发现,恳请指出!你轻轻地点了个赞,那将在我的心里世界增添一颗明亮而耀眼的星!

编辑编辑器 2万+

一篇读懂设计模式

软件设计模式(Software Design Pattern),又称设计模式,是一套被反复使用、多 数人知晓的、经过分类编目的、代码设计经验的总结。它描述了在软件设计过程中的一些不 断重复发生的问题,以及该问题的解决方案。也就是说,它是解决特定问题的一系列套路, 是前辈们的代码设计经验的总结,具有一定的普遍性,可以反复使用。其目的是为了提高代 码的可重用性、代码的可读性和代码的可靠性提供一个创建产品族的接口,其每个子类可以生产一系列相关的产品。客户类和工厂类分开。

haidi8 774

一、23种设计模式系列导引

1995 年,GoF(Gang of Four,四人组/四人帮)合作出版了《设计模式:可复用面向对象软件的基础》一书,共收录了 23 种设计模式,从此树立了软件设计模式领域的里程碑,人称「GoF设计模式」。描述程序在运行时复杂的流程控制,即描述多个类或对象之间怎样相互协作共同完成单个对象都无法单独完成的任务,它涉及算法与对象间职责的分配。关注点是“怎样创建对象”,特点是“将对象的创建与使用分离”,使用者不需要关注对象的创建细节,对象的创建由相关的工厂来完成。只和朋友交流,不和陌生人说话,减少代码臃肿。

寓教于乐。教己助人 158

分与合:重新读懂 GoF 23 种设计模式

本文从"分与合"的视角重新解读GoF 23种设计模式。软件设计中,"分"用于解耦和隔离变化,"合"旨在统一入口和复用资源。设计模式可分为三类:11个"分"模式(如Bridge分离抽象与实现、Strategy分派算法),7个"合"模式(如Singleton归并实例、Facade统一接口),以及5个"分合一体"模式(如Composite同时实现分解与组合)。这种分类方式揭示了设计模式的本质思想:在适当层面进行分离或组合,以平衡灵活性与复杂性。文章通过清晰图表和典型示例,展示了每种模式如何体现分合原则。

d3y1`5 81_09 618

1张表格读懂23种设计模式,让你从小兵向大咖迈进

软件设计模式(Design pattern),又称设计模式,是一套被反复使用、多数人知晓的、经过分类编目的、代码设计经验的总结。使用设计模式是为了可重用代码、让代码更容易被他人理解、保证代码可靠性、程序的重用性。(来源于百度百科)

zoekimjun的专栏 350
上一篇: 一文带你读懂:设计模式的六大原则
下一篇: 23天读懂23种设计模式:工厂方法模式(创建型)
后台技术汇
博客等级 码龄11年 670粉丝 531原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

后台技术汇

对你的帮助,是对我的最好鼓励。

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值