Flyweight 享元
射击游戏编程中,同一样式的子弹位图占一定的内存空间且该部分内容改动较少,一个子弹对象不应该持有一张位图,而是只持有位图的地址或者索引或者享元对象的引用(保证可以找到位图即可),这样即使有许许多多的子弹对象,也不会有重复位图占用大量空间。
The flyweight is to make the memory can load more objects. An object may have some properties that is repeating, and it take many memory space, we move these properties into another class(called Flyweight), and the original class just hold a reference of the Flyweight instance.
享元可以使内存能加载更多的对象。一个对象可能会拥有一些重复的、占用空间大的属性,我们将这些属性移到另外的一个类中(这个类称为享元),然后原来的类就只是持有一个享元实例的引用。
// Client
class Game {
var bullets: [Bullet] = []
var factory: Factory
func creatBullet(_ count: Int) {
for i in 0..<count {
var b = Bullet(id: i, position: [Int.random(in: 0...20), Int.random(in: 0...20)], paint: factory.getBulletPaint(sign: BulletPaint.sign))
bullets.append(b)
}
}
init() {
factory = Factory()
}
}
// Context
class Bullet {
var id: Int
var position: [Int] = [0, 0]
var paint: BulletPaint
init(id: Int, position: [Int], paint: BulletPaint) {
self.id = id
self.position = position
self.paint = paint
}
}
// Flyweight
class BulletPaint {
var picture: String?
static var sign = 0
func changePicture(picture: String) {
self.picture = picture
BulletPaint.sign += 1
}
}
// Flyweight Factory
class Factory {
private var stuff: [BulletPaint] = []
func getBulletPaint(sign: Int) -> BulletPaint {
if stuff.count <= sign || stuff[sign] == nil {
var paint = BulletPaint()
stuff.append(paint)
return paint
}
return stuff[sign]
}
}
var game = Game()
game.creatBullet(100)
把“重量级”但又不是个性化(其它类可能也有一模一样的,所以会引起大量重复)的属性交给公共的类去存放,可以减轻原来类的负担。所以享元本意是 “Flyweight” 即 “减轻重量”,这样不同的类也可以通过那个共同的类来共享那些相同的属性。
享元模式适用于改动极少、占用空间较大、重复性大的对象属性。