享元(Flyweight)模式是一种结构型设计模式, 它摒弃了在每个对象中保存所有数据的方式, 通过共享多个对象所共有的相同状态, 让你能在有限的内存容量中载入更多对象。
当对象有一些可以共享的内部属性或当需要创建大量对象以至于可能会引起内存问题时,可以考虑使用享元模式。
比如系统中每个用户都可以拥有一枚勋章,普通实现我们可以将为每个用户实例创建设置一枚新勋章实例,或者使用享元模式只创建一枚勋章,由全部用户共享。这样即使有100万个用户我也只需要创建一枚勋章,而不是创建100万个勋章实例。
代码示例:
package main
import "fmt"
// 勋章
type Badge struct {
name string
}
// 创建勋章实例
func NewBadge(name string) *Badge {
return &Badge{
name: name,
}
}
// 勋章享元
type BadgeFlyweight struct {
badges map[string]*Badge
}
// 返回享元对象
func (b *BadgeFlyweight) Get(name string) *Badge {
badge := b.badges[name]
if badge == nil {
badge = NewBadge(name)
b.badges[name] = badge
}
return badge
}
// 勋章享元实例
var badgeFlyweight *BadgeFlyweight
// 用户
type User struct {
*Badge
}
// 创建用户实例
func NewUser(badgeName string) *User {
if badgeFlyweight == nil {
badgeFlyweight = &BadgeFlyweight{
badges: make(map[string]*Badge),
}
}
// 设置用户勋章
badge := badgeFlyweight.Get(badgeName)
return &User{
Badge: badge,
}
}
func main() {
// 用户1设置粉丝勋章
user1 := NewUser("fans")
fmt.Printf("user1:%+v\n", user1)
// 用户2也设置粉丝勋章,两个用户共享同于个勋章实例
user2 := NewUser("fans")
fmt.Printf("user2:%+v\n", user2)
fmt.Println(user1.Badge == user2.Badge)
}
运行代码,输出结果:
user1:&{Badge:0xc000014090}
user2:&{Badge:0xc000014090}
true