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

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

前言

单例模式是最简单的一种模式。在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.lqws.cn/news/450379.html

相关文章:

  • Deepseek+墨刀,1min快速生成流程图!
  • iOS APP上架App Store实践:通过自动化流程和辅助工具高效提
  • 传输层协议UDP/TCP
  • Linux运维笔记:在 Ubuntu 工作站上安装 PyCharm 社区版并配置多用户访问
  • 悦数图数据库v5.1原生向量赋能
  • 【时时三省】(C语言基础)善于利用指针
  • 传感器:基于STM32F103/407系AHT20温湿度传感器数据采集
  • C#学习日记
  • STM32学习笔记:深入浅出解析CAN总线
  • 【生活点滴】车辆过户、新车挂牌
  • 基于物联网的智能衣柜系统设计
  • 变幻莫测:CoreData 中 Transformable 类型面面俱到(五)
  • 探秘阿里云云数据库Tair:性能、特性与应用全景解析
  • 基于大模型的三叉神经痛预测及治疗方案研究报告
  • [持续集成]
  • 腾讯云COS“私有桶”下,App如何安全获得音频调用流程
  • 效果成本双突破!快手提出端到端生成式推荐系统OneRec!
  • CSS知识补充 --- 控制继承
  • C++网络编程入门学习(五)-- CMake 学习笔记
  • 51单片机重要知识点1
  • git更改远端文件名称以及删除指定文件夹
  • 【Mini-F5265-OB开发板试用测评】3、MDS 可编程 IP 互联模块
  • npm下载离线依赖包
  • 算法-每日一题(DAY11)每日温度
  • CDGP|2025年传统工厂数据治理:智能制造升级的新引擎
  • ESP32-HTML-08
  • .Net Framework 4/C# 进程和线程的使用
  • .NET 4.7中使用NLog记录日志到数据库表
  • 基于PyQt5和PaddleSpeech的中文语音识别系统设计与实现(Python)
  • 数字媒体专业核心课程体系以“艺术创意+数字科技+产业应用”三维融合