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

go设计模式——单例模式

概念

单例是一种创建型设计模式,它确保一个类在整个程序运行期间只有一个实例并提供一个全局访问点来使用该实例。虽然单例模式在某些情况下非常有用,例如管理全局配置、日志记录或资源共享,但它也带来了与全局变量相似的问题。具体来说,单例模式可能导致代码的模块化和可测试性下降,因为它在整个系统中引入了隐式依赖,使得代码难以解耦和扩展。因此,尽管单例模式可以简化某些设计,但在使用时需要谨慎,以避免对代码的灵活性和可维护性产生不良影响。

demo1

单例模式grpc的连接

package clientimport ("log""sync""google.golang.org/grpc""your/proto/package/path/example" // 更新为你的 proto 包路径
)type GRPCClient struct {conn   *grpc.ClientConnclient example.ExampleServiceClientmu     sync.Mutex
}var instance *GRPCClient
var once sync.Once// GetGRPCClient 返回 ExampleServiceClient 的单例实例
func GetGRPCClient() *GRPCClient {once.Do(func() {instance = &GRPCClient{}})// 获取锁来保护连接状态检查instance.mu.Lock()defer instance.mu.Unlock()// 如果连接为空或已关闭,则重新建立连接if instance.conn == nil || instance.conn.GetState() == grpc.Shutdown {conn, err := grpc.Dial("localhost:50051", grpc.WithInsecure())if err != nil {log.Fatalf("Failed to connect to gRPC server: %v", err)}instance.conn = conninstance.client = example.NewExampleServiceClient(conn)}return instance
}// GetClient 返回 gRPC 客户端
func (g *GRPCClient) GetClient() example.ExampleServiceClient {return g.client
}// CloseConnection 关闭 gRPC 连接
func (g *GRPCClient) CloseConnection() error {g.mu.Lock()defer g.mu.Unlock()if g.conn != nil {err := g.conn.Close()g.conn = nil // 重置连接,确保下一次调用时可以重新连接return err}return nil
}

demo1

你想要在程序中创建一个“月亮”对象,并确保在整个程序运行期间,只有一个这样的“月亮”对象存在。这个对象应该是私有的,不可以被其他地方直接访问或修改。就是我们的desc是不允许外部修改的

package singletonimport "sync"// sync.Once 确保月亮单例实例只会被创建一次
var once sync.Once// moon 是一个不可导出的结构体
type moon struct {description string
}func (m *moon) String() string {return m.description
}// theMoon 是 moon 类型的单例实例
var theMoon *moon// TheMoon 返回月亮单例实例
func TheMoon() *moon {// 使用 sync.Once 确保 theMoon 只会被初始化一次once.Do(func() {theMoon = &moon{description: "美丽的月亮,照亮夜空。",}})return theMoon
}

使用场景

1. 全局配置管理

• 在应用程序中,配置通常是全局的,且不希望在多个地方加载配置文件。使用单例模式可以确保配置文件只被加载一次,并在应用程序的整个生命周期内共享同一个配置实例。

2. 日志记录

• 日志记录器通常需要在应用程序的不同部分被调用,但希望所有日志都通过同一个实例处理,以便统一管理日志的输出目标、格式等。单例模式可以保证只有一个日志记录器实例在整个程序中被使用。

3. 数据库连接池

• 数据库连接是一个昂贵的资源,通常希望应用程序共享一个连接池来管理数据库连接。通过单例模式,可以确保连接池实例在整个应用程序中是唯一的,并且被多个客户端共享。

4. 缓存管理

• 在一些应用中,缓存管理通常需要一个全局的管理对象来管理缓存数据。单例模式可以用于确保缓存管理对象在应用中只有一个实例,从而避免多次实例化带来的资源浪费。

5. 线程池

• 在并发编程中,线程池用于管理线程的复用,以避免频繁创建和销毁线程带来的开销。通过单例模式,可以确保线程池在整个应用中只有一个实例,并为所有任务共享。

6. 设备或资源管理

• 一些应用需要管理有限的设备或资源,如打印机、显卡等。这些设备通常不希望被多个实例同时控制,因此可以使用单例模式确保对设备的管理是通过单一实例完成的。

相关文章:

  • 北京网站建设多少钱?
  • 辽宁网页制作哪家好_网站建设
  • 高端品牌网站建设_汉中网站制作
  • Mybatis插件:慢sql存储到数据库
  • 简单步骤获取IP地址SSL 证书
  • C/C++控制台贪吃蛇游戏的实现
  • go中 panicrecoverdefer机制
  • python构建一个web程序
  • 浪潮服务器NVME 硬盘通过 Intel VROC 做RAID
  • MySQL中处理JSON数据:大数据分析新方向,技术详解与应用场景
  • LabVIEW深度监测系统
  • 实验九:点阵屏实验
  • Linux云计算 |【第二阶段】SECURITY-DAY5
  • 零基础5分钟上手谷歌云GCP - 服务器自动扩展
  • Go 使用Redis安装、实例和基本操作
  • Redis数据类型
  • 【cocos creator】2.x里,使用3D射线碰撞检测
  • 通过proxy和普通模式实现单例
  • 9月CHINA-PUB-OPENDAY技术沙龙——IPHONE
  • @jsonView过滤属性
  • 【剑指offer】让抽象问题具体化
  • Django 博客开发教程 16 - 统计文章阅读量
  • Electron入门介绍
  • EventListener原理
  • Java深入 - 深入理解Java集合
  • Netty+SpringBoot+FastDFS+Html5实现聊天App(六)
  • overflow: hidden IE7无效
  • Promise初体验
  • React Native移动开发实战-3-实现页面间的数据传递
  • Vue.js-Day01
  • vue--为什么data属性必须是一个函数
  • windows-nginx-https-本地配置
  • XML已死 ?
  • 从0实现一个tiny react(三)生命周期
  • 分类模型——Logistics Regression
  • 分享一个自己写的基于canvas的原生js图片爆炸插件
  • 记录一下第一次使用npm
  • 利用jquery编写加法运算验证码
  • 聊聊flink的BlobWriter
  • 漫谈开发设计中的一些“原则”及“设计哲学”
  • 少走弯路,给Java 1~5 年程序员的建议
  • 视频flv转mp4最快的几种方法(就是不用格式工厂)
  • - 转 Ext2.0 form使用实例
  • ​​​​​​​sokit v1.3抓手机应用socket数据包: Socket是传输控制层协议,WebSocket是应用层协议。
  • ​Z时代时尚SUV新宠:起亚赛图斯值不值得年轻人买?
  • ​中南建设2022年半年报“韧”字当头,经营性现金流持续为正​
  • # Apache SeaTunnel 究竟是什么?
  • # 数仓建模:如何构建主题宽表模型?
  • ### RabbitMQ五种工作模式:
  • #【QT 5 调试软件后,发布相关:软件生成exe文件 + 文件打包】
  • #14vue3生成表单并跳转到外部地址的方式
  • #我与Java虚拟机的故事#连载03:面试过的百度,滴滴,快手都问了这些问题
  • (k8s中)docker netty OOM问题记录
  • (react踩过的坑)Antd Select(设置了labelInValue)在FormItem中initialValue的问题
  • (分布式缓存)Redis分片集群
  • (附源码)node.js知识分享网站 毕业设计 202038
  • (附源码)php投票系统 毕业设计 121500
  • (附源码)ssm高校实验室 毕业设计 800008