单例设计模式是软件编程中最重要和最常用的设计模式之一。它确保类在应用程序运行时只有一个实例,并提供对该实例的全局访问点。在这篇文章中,我们将讨论 Singleton 的重要性、如何在 Golang 中实现它以及它带来的好处,特别是在并发环境中。
单例是一种将类的实例限制为单个实例的设计模式。它在需要单点控制或单个共享资源的情况下特别有用,例如:
我将列出一些关于 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。
以上是单例设计模式的详细内容。更多信息请关注PHP中文网其他相关文章!