[设计模式]创建型模式-单例模式

前言

单例模式是最简单的一种模式。在Go中,单例模式指的是全局只有一个实例,并且它负责创建自己的对象。单例模式有减少内存和系统资源开销、防止多个实例产生冲突等优点。

因为单例模式保证了实例的全局唯一性,并且只被初始化一次,所以比较适合全局共享一个实例,且只需要被初始化一次的场景,例如数据库实例、全局配置、全局任务池等。

单例模式又分为饿汉方式和懒汉方式。饿汉方式是指全局的单例实例在包被加载时创建,而懒汉方式指全局的单例实例在第一次被使用时创建。其中懒汉方式是开源项目中使用最多的方式。

示例代码

Go

懒汉方式的缺点是非并发安全,实际使用中一般加锁,或者使用sync.Once

package singleton  import "sync"  type Singleton interface {  foo()  
}  type singleton struct{}  func (s singleton) foo() {}  var (  instance *singleton  once     sync.Once  
)  func GetInstance() Singleton {  once.Do(func() {  instance = &singleton{}  })  return instance  
}

单元测试

package singleton  import (  "sync"  "testing")  const parCount = 100  func TestSingleton(t *testing.T) {  ins1 := GetInstance()  ins2 := GetInstance()  if ins1 != ins2 {  t.Fatal("instance is not equal")  }  
}  func TestParallelSingleton(t *testing.T) {  start := make(chan struct{})  wg := sync.WaitGroup{}  wg.Add(parCount)  instance := [parCount]Singleton{}  for i := 0; i < parCount; i++ {  go func(index int) {  <-start  instance[index] = GetInstance()  wg.Done()  }(i)  }  close(start)  wg.Wait()  for i := 1; i < parCount; i++ {  if instance[i] != instance[i-1] {  t.Fatal("instance is not equal")  }  }  
}

Python

python的包是天然的单例模式,只要放到单独的包中,import时就是引用的单例。

如果要在一个包内使用设计模式,也有以下几种方式。

使用函数装饰器实现单例
def singleton(cls):  _instance = {}  def inner():  if cls not in _instance:  _instance[cls] = cls()  return _instance[cls]  return inner  @singleton  
class MyCls:  def __init__(self):  pass  if __name__ == "__main__":  a = MyCls()  b = MyCls()  print(id(a) == id(b))  # 输出结果应为 True
使用类装饰器实现单例
class Singleton:  def __init__(self, cls):  self._cls = cls  self._instance = {}  def __call__(self):  if self._cls not in self._instance:  self._instance[self._cls] = self._cls()  return self._instance[self._cls]  @Singleton  
class MyCls:  def __init__(self):  pass  if __name__ == "__main__":  a = MyCls()  b = MyCls()  print(id(a) == id(b))  # 输出结果应该是True

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

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

相关文章

嵌入式开发之嵌入式系统硬件架构设计时,如何选择合适的微处理器/微控制器?

在嵌入式系统硬件架构设计中,选择合适的微处理器 / 微控制器(MCU/MPU)是关键环节,需从多维度综合评估。以下是系统化的选择策略及核心考量因素: 一、明确应用需求与核心指标 1. 性能需求 处理能力:根据任务复杂度确定主频、指令集架构(ISA)。 简单控制任务(如家电开…

《汇编语言:基于X86处理器》第3章 复习题和练习,编程练习

本篇记录《汇编语言&#xff1a;基于X86处理器》第3章 复习题和练习&#xff0c;编程练习的学习。 3.9复习题和练习 3.9.1 简答题 1.举例说明三种不同的指令助记符。 答&#xff1a;MOV&#xff0c;ADD和MUL。 2.什么是调用规范?如何在汇编语言声明中使用它? 答&#x…

基于STM32六路温度监测上下限报警

基于STM32六路温度监测报警 &#xff08;仿真&#xff0b;程序&#xff09; 功能介绍 具体功能&#xff1a; 1.DS18B20测得的六路温度值&#xff1b; 2.LCD1602实时显示六路温度值&#xff1b; 3.当某一路超出温度设定上下限&#xff0c;对应蜂鸣器会报警&#xff1b; 硬件…

七、Redis的持久化策略

两种持久化策略: Redis这个缓存存放的数据是存到内存的&#xff0c;假如宕机了&#xff0c;那么就会数据丢失。如何避免这种情况呢&#xff1f;由此&#xff0c;Redis推出了两种持久化机制。 第一种机制就是以二进制序列形式存储数据的RDB快照&#xff0c;第二种机制就是以命令…

GVim-vimrc 字体缩放与界面优化配置

GVim-vimrc 字体缩放与界面优化配置 文章目录 GVim-vimrc 字体缩放与界面优化配置背景问题解决方案1. 字体大小调整函数增加字体大小函数减少字体大小函数 2. 快捷键映射3. 自定义命令 附加界面优化光标行列高亮 完整配置使用技巧 背景问题 在使用Vim编辑器时&#xff0c;我们…

Oracle|Oracle SQL*Plus 配置上下翻页功能

在数据库管理工作中&#xff0c;高效的命令行操作体验对于提升工作效率至关重要。本文将详细介绍如何通过安装 rlwrap 工具并进行环境变量配置&#xff0c;让 SQL*Plus 获得现代化的命令行体验&#xff0c;助力数据库操作效率的大幅提升。 一、安装准备&#xff1a;创建软件目…

PowerShell读取CSV并遍历组数组

在 PowerShell 中&#xff0c;从 CSV 文件获取 Group 列的数据并遍历输出&#xff0c;可以按照以下步骤操作&#xff1a; 步骤说明&#xff1a; 读取 CSV 文件&#xff1a;使用 Import-Csv 命令加载 CSV 数据。 提取 Group 数组&#xff1a;通过管道操作 | Select-Object -Ex…

【unitrix】 3.7 类型级加一计算(Add1.rs)

一、源码 这段代码实现了一个类型级别的加法操作&#xff08;Add1 trait&#xff09;&#xff0c;允许在编译时对数字类型进行加一操作。它使用了类型系统来表示数字&#xff08;如 Z0、P1、N1 等&#xff09;&#xff0c;并定义了它们的加一行为。 //! 加一操作特质实现 / I…

据字典是什么?和数据库、数据仓库有什么关系?

目录 一、数据字典的定义及作用 1. 对于数据开发者 2. 对于业务人员 3. 对于数据管理员 二、数据字典的组成 1. 数据项 2. 数据结构 3. 数据流 4. 数据存储 5. 处理过程 三、数据字典与数据库的关系 1. 数据字典是数据库的重要组成部分 2. 数据字典为数据库设计和…

附加日志会跟随着expdp一起导出吗

数据泵在导出数据表时会不会带着附加日志一起导出&#xff0c;可以使用数据泵导入参数sqlfile进行sql追踪。 实验 1.新建测试表 SQL> create table Benjamin.tb_test (id int); Table created.SQL> alter table Benjamin.tb_test add supplemental log data(all) colu…

Python漂浮的爱心

系列文章 序号直达链接Tkinter1Python李峋同款可写字版跳动的爱心2Python跳动的双爱心3Python蓝色跳动的爱心4Python动漫烟花5Python粒子烟花Turtle1Python满屏飘字2Python蓝色流星雨3Python金色流星雨4Python漂浮爱心5Python爱心光波①6Python爱心光波②7Python满天繁星8Pytho…

3、做中学 | 二年级上期 Golang数据类型和常量/变量声明使用

一、基本数据类型 在 Go 编程语言中&#xff0c;数据类型用于声明函数和变量。 数据类型的出现是为了把数据分成所需内存大小不同的数据&#xff0c;编程的时候需要用大数据的时候才需要申请大内存&#xff0c;就可以充分利用内存。 Go 基本数据类型 类别类型描述零值示例取…

php5 与 mysql8的兼容问题

php5 与 mysql8的兼容问题 环境 Linux: ubuntu20.04 Mysql&#xff1a; 8.0.33 Php: 5.6 代码 # cat test.php <?php$link mysqli_connect("127.0.0.1", "root", "123456");if ($link) {echo "ok"; } else {echo "fail&…

从0开始学linux韦东山教程Linux驱动入门实验班(1)

本人从0开始学习linux&#xff0c;使用的是韦东山的教程&#xff0c;在跟着课程学习的情况下的所遇到的问题的总结,理论虽枯燥但是是基础。本人将前几章的内容大致学完之后&#xff0c;考虑到后续驱动方面得更多的开始实操&#xff0c;后续的内容将以韦东山教程Linux驱动入门实…

MSPM0G3507学习笔记(二) 超便捷配置led与按键

电赛备赛中&#xff0c;打算系统过一遍MSPM0G3507的各个部分&#xff0c;同时把过程记录下来。本系列以代码全部能用复用性、可移植性高为目的。本系列所有的代码会开源至github&#xff0c;如果觉得有用&#xff0c;请点个赞/给我的github仓库点一颗star吧。 github地址&…

day03-微服务01

【黑马程序员SpringCloud微服务技术栈实战教程&#xff0c;涵盖springcloud微服务架构Nacos配置中心分布式事务等】 暂时无法在飞书文档外展示此内容 之前我们学习的项目一是单体项目&#xff0c;可以满足小型项目或传统项目的开发。而在互联网时代&#xff0c;越来越多的一线…

嵌入式Linux系统内存占用率高的原因、后果与防控全解析

作者&#xff1a;嵌入式Jerry 【欢迎关注“嵌入式Jerry”&#xff0c;获取更多Linux/驱动/性能实战干货】 推荐阅读&#xff1a;《Yocto项目实战教程&#xff1a;高效定制嵌入式Linux系统》 京东正版促销&#xff0c;支持作者&#xff01;https://item.jd.com/15020438.html 嵌…

【案例分享】如何用 DHTMLX Scheduler 构建灵活高效的资源调度系统?

在企业信息化进程加速的今天&#xff0c;资源调度与任务管理已成为ERP系统中的关键模块。今天&#xff0c;我们带来了一个来自 X-Interactive 的精彩应用案例&#xff0c;看他们如何借助 DHTMLX Scheduler 实现更智能的任务分配与资源规划。 DHTMLX Scheduler 试用下载 &…

Kafka 向 TDengine 写入数据

TDengine Kafka Connector 包含 TDengine Source Connector 和 TDengine Sink Connector 两个插件。用户只需提供简单的配置文件&#xff0c;就可以将 Kafka 中指定 topic 的数据&#xff08;批量或实时&#xff09;同步到 TDengine&#xff0c;或将 TDengine 中指定数据库的数…

智慧医院核心引擎:IBMS 系统守护医疗环境高效与安全​

在医疗场景中&#xff0c;时间就是生命&#xff0c;效率与安全容不得分毫差错。传统医院面临着设备管理分散、应急响应迟缓、能耗居高不下等难题&#xff0c;严重制约医疗服务质量与运营效率。而 IBMS 系统&#xff0c;作为智慧医院的核心引擎&#xff0c;以尖端科技重塑医疗环…