享元模式是什麼 享元模式:是一種結構型設計模式,它允許你在消耗少量的記憶體的情況下支持大量的對象。享元模式通過共用多個對象的部分狀態來實現上述功能。即是享元模式會將不同對象的相同功能緩存以節省記憶體。 為什麼用享元模式 如果程式中有很多相似對象,這時候你就可以用享元模式來節約記憶體。 享元模式怎麼實現 這 ...
享元模式是什麼
享元模式:是一種結構型設計模式,它允許你在消耗少量的記憶體的情況下支持大量的對象。享元模式通過共用多個對象的部分狀態來實現上述功能。即是享元模式會將不同對象的相同功能緩存以節省記憶體。
為什麼用享元模式
如果程式中有很多相似對象,這時候你就可以用享元模式來節約記憶體。
享元模式怎麼實現
這裡用dressFactorySingleInstance這個包常量來保存dress,用dressMap的key來對不同的dress分類。這個例子就是在這裡達到共用的功能,因為無論多少玩家,而dress只有兩類。所以無論多少玩家,dressFactorySingleInstance中的dress只有兩個key,來達到dress共用。
dress_factory.go
package flyweight
import "fmt"
const (
TerroristDressType = "tDress"
CounterTerroristDressType = "ctDress"
)
type dressFactory struct {
dressMap map[string]dress
}
var dressFactorySingleInstance = &dressFactory{
dressMap: make(map[string]dress,2),
}
func getDressFactorySingleInstance() *dressFactory {
return dressFactorySingleInstance
}
func (d *dressFactory) getDressByType(dressType string) (dress, error) {
if d.dressMap[dressType] != nil {
return d.dressMap[dressType], nil
}
if dressType == TerroristDressType {
d.dressMap[dressType] = newTerroristDress()
return d.dressMap[dressType], nil
}
if dressType == CounterTerroristDressType {
d.dressMap[dressType] = newCounterTerroristDress()
return d.dressMap[dressType], nil
}
return nil, fmt.Errorf("Wrong dress type passed")
}
dress.go
package flyweight
type dress interface {
getColor() string
}
type counterTerroristDress struct {
color string
}
func (c *counterTerroristDress) getColor() string {
return c.color
}
func newCounterTerroristDress() *counterTerroristDress {
return &counterTerroristDress{color: "green"}
}
type terroristDress struct {
color string
}
func (t *terroristDress) getColor() string {
return t.color
}
func newTerroristDress() *terroristDress {
return &terroristDress{color: "red"}
}
game.go客戶端代碼
package flyweight
type player struct {
dress dress
playerType string
}
func newPlayer(playerType, dressType string) *player {
dress, _ := getDressFactorySingleInstance().getDressByType(dressType)
return &player{
playerType: playerType,
dress: dress,
}
}
type game struct {
terrorists []*player
counterTerrorists []*player
}
func newGame() *game {
return &game{
terrorists: make([]*player,0,1),
counterTerrorists: make([]*player,0,1),
}
}
func (c *game) addTerrorist(dressType string) {
player := newPlayer("T", dressType)
c.terrorists = append(c.terrorists, player)
return
}
func (c *game) addCounterTerrorist(dressType string) {
player := newPlayer("CT", dressType)
c.counterTerrorists = append(c.counterTerrorists, player)
return
}
main.go客戶端代碼
func main() {
game := newGame()
//Add Terrorist
game.addTerrorist(TerroristDressType)
game.addTerrorist(TerroristDressType)
//Add CounterTerrorist
game.addCounterTerrorist(CounterTerroristDressType)
game.addCounterTerrorist(CounterTerroristDressType)
dressFactoryInstance := getDressFactorySingleInstance()
for dressType, dress := range dressFactoryInstance.dressMap {
fmt.Printf("DressColorType: %s\nDressColor: %s\n", dressType, dress.getColor())
}
}
// 結果:
//DressColorType: tDress
//DressColor: red
//DressColorType: ctDress
//DressColor: green
優點
- 如果程式中有很多相似對象, 那麼你將可以節省大量記憶體。
缺點
- 代碼會變得更加複雜。 團隊中的新成員總是會問:“為什麼要像這樣拆分一個實體的狀態?”。
- 你可能需要犧牲執行速度來換取記憶體,因為他人每次調用享元方法時都需要重新計算部分情景數據。