享元模式 - Flyweight Pattern
用途
節省記憶體和資源,並提高的效能
classDiagram
ConcreteFlyweight ..|> IFlyweight
UnsharedConcreteFlyweight ..|> IFlyweight
Context ..> IFlyweight
Context ..> Factory
Factory ..> IFlyweight
Client ..> Context
namespace Flyweight {
class IFlyweight{
<<Interface>>
+Operation()
}
class ConcreteFlyweight{
-Object state
+Operation()
}
class UnsharedConcreteFlyweight{
-Object state
+Operation()
}
class Factory{
-Dictionary<string, IFlyweight> flyweights
+GetFlyweight(string key)
}
class Context{
-Factory factory
-List<IFlyweight> flyweights
+CreateFlyweight(Object options)
}
}
class Client{
+Operation()
}
例子
當談到享元模式(Flyweight Pattern)時,我們可以以一個生活中的例子來解釋
假設你是一位遊戲開發者,正在開發一個多人射擊遊戲
在這個遊戲中,你需要創建許多不同的角色,包括不同種類的士兵和敵人
使用享元模式,你可以節省記憶體和資源,並提高遊戲的效能
你可以將那些具有共享特徵的角色,例如外觀和行為,提取出來並共用,而不是為每個角色創建一個獨立的物件
舉個例子,假設你有多個士兵角色,它們之間的外觀和行為非常相似,唯一的區別可能只是顏色和武器
在享元模式中,你會創建一個士兵享元工廠,該工廠負責管理和提供士兵物件
當遊戲需要創建士兵時,你可以向享元工廠請求一個士兵物件,並提供所需的參數,例如顏色和武器
享元工廠會檢查是否已經存在具有相同參數的士兵物件,如果存在,則返回該物件的引用,否則創建一個新的士兵物件並將其加入享元池中
這樣一來,不同士兵之間可以共享相同的外觀和行為,只有具有不同參數的部分是獨立的
這樣可以節省大量的記憶體和資源,同時提高遊戲的效能
請注意,享元模式適用於具有大量重複性物件的情況,並且這些物件可以在某些方面共享
它的目標是減少內存使用和提高效能
Product
1
2
3
4
5
// 遊戲角色介面
public interface ICharacter
{
void Display();
}
Concrete Product
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
// 具體角色類別
public class Warrior : ICharacter
{
private string name;
private int level;
public Warrior(string name, int level)
{
this.name = name;
this.level = level;
}
public void Display()
{
Console.WriteLine($"Warrior - Name: {name}, Level: {level}");
}
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
public class Mage : ICharacter
{
private string name;
private int level;
public Mage(string name, int level)
{
this.name = name;
this.level = level;
}
public void Display()
{
Console.WriteLine($"Mage - Name: {name}, Level: {level}");
}
}
Factory
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
// 角色工廠
public class CharacterFactory
{
private Dictionary<string, ICharacter> characters = new Dictionary<string, ICharacter>();
public ICharacter GetCharacter(string characterType, string name, int level)
{
// 檢查角色是否已存在,如果存在則返回該角色
if (characters.ContainsKey(characterType))
{
return characters[characterType];
}
else
{
// 如果角色不存在,則根據角色類型創建一個新角色並將其添加到字典中
ICharacter character;
switch (characterType)
{
case "Warrior":
character = new Warrior(name, level);
break;
case "Mage":
character = new Mage(name, level);
break;
default:
throw new ArgumentException($"Invalid character type: {characterType}");
}
characters.Add(characterType, character);
return character;
}
}
}
Context
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
// 使用範例
public class Game
{
private CharacterFactory characterFactory = new CharacterFactory();
public void CreateCharacter(string characterType, string name, int level)
{
// 從角色工廠獲取角色物件
ICharacter character = characterFactory.GetCharacter(characterType, name, level);
// 創建角色並加入遊戲
// ...
}
}
Client
1
2
3
4
var game = new Game();
game.CreateCharacter("Mage", "David", 1);
game.CreateCharacter("Warrior", "Marry", 10);
延伸
本文章以 CC BY 4.0 授權