享元模式在Go中通过结构体封装内在状态、客户端传入外在状态实现共享;使用sync.Map工厂缓存不可变享元指针,避免复制,确保高效复用。

享元模式的核心是“共享不变的部分,分离可变的部分”,在 Go 中没有传统面向对象的继承体系,但通过结构体、接口和指针,完全可以高效实现享元模式——关键是把**内在状态(intrinsic state)封装为共享对象,外在状态(extrinsic state)由客户端管理并传入操作中**。
享元对象应是轻量、不可变(或仅含只读字段),通常用结构体定义,并避免持有外部依赖。例如,渲染不同颜色和位置的圆点时,颜色可共享,坐标则由调用方传入:
type CircleFlyweight struct {
Color string // 内在状态:共享、不可变
}
func (c *CircleFlyweight) Draw(x, y float64) {
fmt.Printf("Drawing a %s circle at (%.1f, %.1f)\n", c.Color, x, y)
}用 sync.Map 或 map + sync.RWMutex 管理已创建的享元,确保相同内在状态只生成一次。推荐使用 sync.Map 提升并发安全性和性能:
type FlyweightFactory struct {
cache sync.Map // key: string (e.g., "red"), value: *CircleFlyweight
}
func (f *FlyweightFactory) Get(color string) *CircleFlyweight {
if val, ok := f.cache.Load(color); ok {
return val.(*CircleFlyweight)
}
fw := &CircleFlyweight{Color: color}
f.cache.Store(color, fw)
return fw
}客户端不直接 new 享元,而是向工厂索取;每次调用方法时,显式传入变化的数据(如位置、尺寸)。这样内存中只有一个 "blue" 实例,却能绘制成百上千个蓝色圆点:
立即学习“go语言免费学习笔记(深入)”;
factory := &FlyweightFactory{}
blue := factory.Get("blue")
red := factory.Get("red")
// 复用同一 blue 实例,仅改变坐标
blue.Draw(10.0, 20.0)
blue.Draw(15.0, 25.0)
blue.Draw(30.0, 40.0)
red.Draw(5.0, 5.0)享元必须以指针形式传递和存储,否则每次赋值都会复制结构体,失去共享意义。同时,确保内在状态字段不被外部修改(Go 中无 private,靠约定+文档约束):
以上就是如何使用Golang实现享元模式_共享对象以节省内存的详细内容,更多请关注php中文网其它相关文章!
每个人都需要一台速度更快、更稳定的 PC。随着时间的推移,垃圾文件、旧注册表数据和不必要的后台进程会占用资源并降低性能。幸运的是,许多工具可以让 Windows 保持平稳运行。
Copyright 2014-2025 https://www.php.cn/ All Rights Reserved | php.cn | 湘ICP备2023035733号