单例设计模式是软件编程中最重要和最常用的设计模式之一。它确保类在应用程序运行时只有一个实例,并提供对该实例的全局访问点。在这篇文章中,我们将讨论 Singleton 的重要性,如何在 Golang 中实现它,以及它带来的好处,特别是在并发环境中。
Singleton 是一种将类的实例限制为单个实例的设计模式。它在需要单点控制或单个共享资源的情况下特别有用,例如:
我将列出一些关于 Pattern 实现的更有意义的观点,同时也表明并非一切都是美好的,我们可能会遇到一些问题。
为了实现单例,我将使用 Golang。在这种语言中,我们必须特别注意并发性,以确保只创建一个实例,即使多个 goroutine 尝试同时访问该实例也是如此。
为了使我们的示例更接近现实世界,让我们为我们的应用程序创建一个记录器。记录器是应用程序中的常用工具,需要唯一以确保日志一致性。
首先,我们定义我们想要拥有单个实例的结构。
package logger import ( "fmt" "sync" ) type Logger struct {} var loggerInstance *Logger
NewInstance函数负责返回Singleton结构的单个实例。我们使用互斥体来确保并发环境中的安全性,实现双重检查锁定以提高效率。
package logger import ( "fmt" "sync" ) type Logger struct{} var logger *Logger var mtx = &sync.Mutex{} func NewInstance() *Logger { if logger == nil { mtx.Lock() defer mtx.Unlock() if logger == nil { fmt.Println("Creating new Logger") logger = &Logger{} } } else { fmt.Println("Logger already created") } return logger }
日志工具总是有一些日志类型,例如Info仅显示信息,Error显示错误等等。这也是过滤我们想要在应用程序中显示的信息类型的一种方法。
因此,让我们创建一个方法来显示 Info 类型的日志。为此,我们将创建一个函数来接收日志消息并将其格式化为 INFO 格式。
package logger import ( "fmt" "sync" "time" ) const ( INFO string = "INFO" ) type Logger struct{} var logger *Logger var mtx = &sync.Mutex{} func NewInstance() *Logger { if logger == nil { mtx.Lock() defer mtx.Unlock() if logger == nil { fmt.Println("Creating new logger") logger = &Logger{} } } else { fmt.Println("Logger already created") } return logger } func (l *Logger) Info(message string) { fmt.Printf("%s - %s: %s\n", time.Now().UTC().Format(time.RFC3339Nano), INFO, message) }
要使用我们的新记录器,我们将在主包中实例化它并创建一个日志以查看此实现的工作原理。
package main import ( "playground-go/pkg/logger" ) func main() { log := logger.NewInstance() log.Info("This is an example of log") }
这是我们运行程序的结果:
Creating new logger 2024-07-03T19:34:57.609599Z - INFO: This is an example of log
如果我们想测试NewInstance是否真的保证只有一个实例在运行,我们可以进行以下测试。
package main import ( "fmt" "playground-go/pkg/logger" ) func main() { log := logger.NewInstance() log.Info("This is an example of log") log2 := logger.NewInstance() log2.Info("This is another example of log") if log == log2 { fmt.Println("same instance") } else { fmt.Println("different instance") } }
我们的日志已更改,现在我们可以看到我们阻止了新实例的创建:
Creating new logger 2024-07-03T19:45:19.603783Z - INFO: This is an example of log Logger already created 2024-07-03T19:45:19.603793Z - INFO: This is another example of log same instance
单例模式是一种强大的工具,可确保应用程序运行时仅存在特定类的一个实例。在记录器示例中,我们了解了如何应用此模式来确保整个应用程序中的日志一致性。
希望这可以帮助您更好地理解 Golang 中的 Singleton。
免责声明: 提供的所有资源部分来自互联网,如果有侵犯您的版权或其他权益,请说明详细缘由并提供版权或权益证明然后发到邮箱:[email protected] 我们会第一时间内为您处理。
Copyright© 2022 湘ICP备2022001581号-3