享元模式是一种结构型设计模式, 它摒弃了在每个对象中保存所有数据的方式, 通过共享多个对象所共有的相同状态, 让你能在有限的内存容量中载入更多对象。
使用场景
- 文本编辑器中的字符对象:在文本编辑器中,字符对象是很多的,但是其中大部分是重复出现的。使用享元模式可以共享相同的字符对象,减少内存占用。
- 游戏中的粒子效果:在游戏开发中,粒子效果是常见的,而且通常会存在大量的粒子对象。使用享元模式可以共享相同的粒子对象,以节省内存和提高性能。
- 操作系统中的字体对象:在操作系统中,字体对象可能会被多个应用程序同时使用。使用享元模式可以共享相同的字体对象,减少内存消耗。
- Web服务器中的连接池:在Web服务器中,经常需要与客户端建立连接。使用享元模式可以共享连接对象,减少连接的创建和销毁开销。
- 图形用户界面中的图标和按钮:在图形用户界面中,图标和按钮是常见的UI元素,而且通常会存在大量的相似对象。使用享元模式可以共享相同的图标和按钮对象,减少内存占用。
代码实现
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55
| package main
import "fmt"
type BulletFlyweight struct { shape string color string damage int }
func NewBulletFlyweight(shape, color string, damage int) *BulletFlyweight { return &BulletFlyweight{ shape: shape, color: color, damage: damage, } }
type Bullet struct { x, y int flyweight *BulletFlyweight }
func NewBullet(x, y int, flyweight *BulletFlyweight) *Bullet { return &Bullet{ x: x, y: y, flyweight: flyweight, } }
func (b *Bullet) Draw() { fmt.Printf("Drawing %s %s bullet at (%d, %d) causing %d damage\n", b.flyweight.color, b.flyweight.shape, b.x, b.y, b.flyweight.damage) }
func main() { sharedBullet := NewBulletFlyweight("round", "red", 10)
bullet1 := NewBullet(0, 0, sharedBullet) bullet2 := NewBullet(10, 20, sharedBullet) bullet3 := NewBullet(5, 15, sharedBullet)
bullet1.Draw() bullet2.Draw() bullet3.Draw() }
|
结语
享元模式适用于需要大量相似对象的场景,通过共享(缓存)对象来减少内存占用和提高性能。通过将对象的内部状态和外部状态分离,享元模式可以实现对象的共享,并且保证对象的外部状态可以在不同的上下文中变化。