单例设计模式是软件编程中最重要和最常用的设计模式之一。它确保类在应用程序运行时只有一个实例,并提供对该实例的全局访问点。在这篇文章中,我们将讨论 Singleton 的重要性,如何在 Golang 中实现它,以及它带来的好处,特别是在并发环境中。
zvvq
什么是单例?
单例是一种将类的实例限制为单个实例的设计模式。它在需要单点控制或单个共享资源的情况下特别有用,例如: zvvq
配置管理器,需要集中应用程序设置。 数据库连接池,必须有效管理有限数量的连接。 记录器,其中日志一致性至关重要。为什么使用单例?
我将列出一些关于 Pattern 实现的更有意义的观点,同时也表明并非一切都是美好的,我们可能会遇到一些问题。 内容来自samhan
好处
全局一致性:确保应用程序的所有点都使用相同的实例,提供数据和行为的一致性。 访问控制:集中控制实例的创建和访问,方便对象生命周期的维护和管理。 资源效率:避免不必要的创建多个实例,节省内存和处理资源。缺点
测试难度:单例会使编写单元测试变得更加困难,因为它们引入了需要管理的全局状态。 增加耦合:过度使用单例会导致组件之间的耦合更紧密,从而使应用程序难以维护和发展。实现单例
为了实现单例,我将使用 Golang。在这种语言中,我们必须特别注意并发性,以确保只创建一个实例,即使多个 goroutine 尝试同时访问该实例也是如此。
内容来自samhan666
为了使我们的示例更接近现实世界,让我们为我们的应用程序创建一个记录器。记录器是应用程序中的常用工具,需要唯一以确保日志一致性。 copyright zvvq
1 - 定义结构
首先,我们定义我们想要拥有单个实例的结构。 内容来自samhan
1 copyright zvvq
2 zvvq
3
内容来自zvvq
4 内容来自samhan
5 内容来自samhan666
6
本文来自zvvq
7 内容来自zvvq,别采集哟
8
内容来自zvvq
9 内容来自samhan666
10 内容来自zvvq
包记录器
zvvq.cn
进口 ( 内容来自zvvq,别采集哟
“FMMT” 本文来自zvvq
“同步” 内容来自zvvq
)
类型记录器结构{}
zvvq
var loggerInstance *Logger
2 - 实现NewInstance函数
NewInstance函数负责返回Singleton结构的单个实例。我们使用互斥锁来确保并发环境中的安全性,实现双重检查锁定以提高效率。 zvvq好,好zvvq
1 本文来自zvvq
2
3 内容来自zvvq
4
5
zvvq好,好zvvq
6
7
8
内容来自zvvq,别采集哟
9 内容来自samhan666
10
zvvq
11 内容来自samhan666
12 zvvq.cn
13
内容来自zvvq
14
zvvq.cn
15 本文来自zvvq
16 内容来自samhan
17 内容来自zvvq,别采集哟
18 zvvq.cn
19
20 zvvq好,好zvvq
21
zvvq.cn
22
内容来自samhan666
23 zvvq.cn
24 内容来自samhan
25 内容来自zvvq,别采集哟
包记录器 copyright zvvq
进口 (
“FMMT” 内容来自zvvq
“同步”
)
内容来自samhan666
类型记录器结构{}
zvvq好,好zvvq
var 记录器*记录器
内容来自zvvq,别采集哟
var mtx = &sync.Mutex{} copyright zvvq
func NewInstance() *记录器 { zvvq.cn
如果记录器 == nil { 内容来自samhan
mtx.Lock()
内容来自zvvq
延迟 mtx.Unlock()
本文来自zvvq
如果记录器 == nil { copyright zvvq
fmt.Println("创建新记录器") 内容来自samhan666
记录器=&记录器{} copyright zvvq
} 内容来自samhan666
} 别的 { 内容来自zvvq
fmt.Println("记录器已创建")
} 内容来自samhan666
返回记录器
}
zvvq
3 - 实现日志类型
日志工具总是有一些日志类型,比如Info只显示信息,Error显示错误等等。这也是过滤我们想要在应用程序中显示的信息类型的一种方法。
所以让我们创建一个方法来显示 Info 类型的日志。为此,我们将创建一个函数来接收日志消息并将其格式化为 INFO 格式。 zvvq.cn
1 本文来自zvvq
2 本文来自zvvq
3
4
5 内容来自samhan
6 内容来自zvvq
7 内容来自samhan
8 内容来自samhan
9
copyright zvvq
10 zvvq.cn
11 zvvq.cn
12 copyright zvvq
13
14 zvvq
15 内容来自zvvq,别采集哟
16 内容来自samhan666
17 本文来自zvvq
18 copyright zvvq
19 zvvq
20 内容来自samhan
21 copyright zvvq
22 zvvq好,好zvvq
23
24 zvvq
25
26
27 zvvq好,好zvvq
28 内容来自samhan
29
内容来自samhan
30
内容来自zvvq,别采集哟
31
内容来自zvvq,别采集哟
32 内容来自samhan
33 copyright zvvq
34
包记录器
进口 ( 内容来自samhan
“FMMT”
“同步”
本文来自zvvq
“团队”
内容来自samhan666
) zvvq.cn
常量( zvvq.cn
信息字符串 =“信息” 内容来自zvvq,别采集哟
) 内容来自zvvq,别采集哟
类型记录器结构{} zvvq好,好zvvq
var 记录器*记录器
var mtx = &sync.Mutex{} zvvq
func NewInstance() *记录器 {
copyright zvvq
如果记录器 == nil {
copyright zvvq
mtx.Lock()
延迟 mtx.Unlock() 内容来自samhan
如果记录器 == nil { 本文来自zvvq
fmt.Println("创建新记录器") 内容来自zvvq,别采集哟
记录器=&记录器{} copyright zvvq
}
} 别的 { 内容来自zvvq
fmt.Println("记录器已创建") zvvq
}
返回记录器
内容来自zvvq,别采集哟
}
func (l *Logger) Info(消息字符串) {
内容来自samhan666
fmt.Printf("%s - %s: %sn", time.Now().UTC().Format(time.RFC3339Nano), INFO, 消息) copyright zvvq
}
内容来自samhan666
4 - 使用记录器
为了使用我们的新记录器,我们将在主包中实例化它并创建一个日志来查看此实现是如何工作的。
1
内容来自samhan666
2 zvvq.cn
3
内容来自samhan
4
内容来自samhan666
5
6 本文来自zvvq
7 zvvq
8 内容来自zvvq,别采集哟
9 内容来自zvvq
10
内容来自samhan666
包主
内容来自samhan666
进口 ( 内容来自samhan
“playground-go/pkg/logger”
) 内容来自zvvq,别采集哟
函数主() {
内容来自samhan
日志 := logger.NewInstance()
log.Info("这是日志的示例") zvvq.cn
}
这是我们运行程序时的结果: 本文来自zvvq
1
内容来自zvvq
2
创建新记录器 zvvq好,好zvvq
2024-07-03T19:34:57.609599Z - 信息:这是日志的示例 内容来自zvvq
如果我们想测试NewInstance是否真的保证只有一个实例在运行,我们可以做以下测试。 zvvq好,好zvvq
1
内容来自zvvq,别采集哟
2 copyright zvvq
3 zvvq好,好zvvq
4 zvvq好,好zvvq
5 内容来自samhan
6
copyright zvvq
7
8
9 zvvq.cn
10 本文来自zvvq
11 zvvq好,好zvvq
12
zvvq
13
14 内容来自samhan666
15 zvvq
16 copyright zvvq
17
内容来自samhan666
18 内容来自samhan
19 内容来自zvvq
20
copyright zvvq
包主 zvvq
进口 (
“FMMT”
“playground-go/pkg/logger” zvvq.cn
)
函数主() { 内容来自samhan666
日志 := logger.NewInstance() 内容来自zvvq
log.Info("这是日志的示例")
log2 := logger.NewInstance()
log2.Info("这是日志的另一个例子") copyright zvvq
如果日志 == log2 {
fmt.Println("同一实例")
zvvq
} 别的 {
zvvq好,好zvvq
fmt.Println("不同的实例")
} copyright zvvq
} 内容来自zvvq
我们的日志已更改,现在我们可以看到我们阻止了新实例的创建:
1 zvvq.cn
2
3
4
5 内容来自samhan
创建新记录器 内容来自samhan
2024-07-03T19:45:19.603783Z - 信息:这是日志的示例
记录器已创建
内容来自samhan666
2024-07-03T19:45:19.603793Z - 信息:这是日志的另一个示例 内容来自samhan
同一实例
copyright zvvq
结论
单例模式是一种强大的工具,可确保应用程序运行时仅存在特定类的一个实例。在记录器示例中,我们了解了如何应用此模式来确保整个应用程序中的日志一致性。
内容来自samhan666
希望这可以帮助您更好地理解 Golang 中的 Singleton。 zvvq
以上就是单例设计模式的详细内容,更多请关注其它相关文章! 内容来自zvvq