全局变量初始化设计模式
为全局变量的获取设计Getter函数,全局变量的初始化函数返回这样的Get函数。
首先是Getter函数的设计
1
2
3
4
func Getter[T any] func() T
func (getter Getter[T]) Get() T {
return getter()
}
假设现在有全局变量GloabalVar, 设计其初始化函数。
1
2
3
4
5
6
7
8
9
10
11
12
func InitGloabalVar(params ...any) Getter[GlobalVar] {
// 进行初始化
var globalVar GlobalVar
return func() {
return globalVar
}
}
func Init() {
GlobalVar = InitGloabalVar()
}
好处:
延迟初始化(Lazy Initialization): 初始化函数可以在真正需要使用全局变量时才进行初始化,从而避免程序一启动就分配不必要的资源,提高效率。
单例模式(Singleton Pattern): 通过封装全局变量的初始化过程,只允许创建一个实例,保证整个程序中获取的全局变量均指向同一个对象,避免因多次创建造成资源浪费或状态不一致的问题。
封装性(Encapsulation): 将初始化逻辑和变量读取分离,用户只需要通过getter函数访问全局变量,而不必关心底层具体的初始化流程,这样有利于后期维护和扩展。
灵活性(Flexibility): 初始化函数支持传递参数(params …any),可以根据不同需求定制初始化流程,使得全局变量的创建更加灵活多变。例如,可以根据环境参数或配置文件来决定变量的初始状态。
可测试性(Testability): 把全局变量的初始化逻辑封装在一个独立的函数中,可以方便地在单元测试中模拟不同的初始化情况,甚至可以利用依赖注入的方式在测试过程中替换全局变量的实现,从而降低测试耦合性。
统一访问接口: 通过Getter函数对外暴露全局变量的访问,形成一个固定接口。即使以后需要改变全局变量的存储或初始化细节,也只需要修改内部实现,而不用修改调用者代码,这有助于代码的演进与重构。
潜在的线程安全扩展: 虽然示例代码未涉及线程安全,但这种设计模式便于在初始化或getter内部加入锁或其他同步机制,来保证在多线程环境下的安全性。
This post is licensed under CC BY 4.0 by the author.