設計模式(C#)——10享元模式
推薦閱讀:
前言
在軟體開發中,當我們需要對某些物件重複建立,且最終只需要得到單一結果。如果使用一般思維,那我們將浪費很多記憶體空間,為此,我們引入享元模式。
介紹
所謂享元模式即共享物件,該模式利用先前建立的已有物件,通過某種規則去判斷當前所需物件是否可以利用原有物件做相應修改後得到想要的效果,如果可以,則只需要修改該物件的某些屬性以達到要求,否則,則建立新物件。享元模式(Flyweight Pattern)主要用於減少建立物件的數量,以減少記憶體佔用和提高效能。
享元模式的要素:
1、抽象享元(Flyweight):它是所有具體享元類的抽象基類,為其子類規定出需要實現的公共介面;
2、具體享元(Concrete Flyweight):具體享元類實現了抽象享元類所規定的介面;
3、享元工廠(FlyweightFactoiy):享元工廠類負責建立和管理享元物件。
下面舉個例子:
例如:在遊戲中敵人的生成,生成的敵人往往是不同的,生成的位置不同,顏色不通等。下面,我們假設生成的是同一種敵人,但是它的y座標不固定。
名稱空間享元模式中包含AbEnemy充當抽象享元,Enemy類充當具體享元,FactoyEnemy工廠類充當享元工廠。本案例通過使用享元模式來實現敵人的生成。
下面使用程式碼實現享元模式:
1.建立抽像享元AbEnemy
public abstract class AbEnemy
{
public string color;
public int x;
public int y;
public AbEnemy()
{
color = "紅";
x = 100;
}
public override string ToString()
{
return string.Format("生成{0}顏色的敵人,位置在X為{1},Y為{2}", color, x, y);
}
}
2.建立具體享元
public class Enemy:AbEnemy
{
public Enemy(int posY)
{
y = posY;
}
}
3.建立一個工廠,生成基於給定資訊的實體類的物件
public class FactoyEnemy
{
private Dictionary<int, Enemy> EnemyList;
public FactoyEnemy()
{
EnemyList = new Dictionary<int, Enemy>();
EnemyList.Add(1, new Enemy(100));
EnemyList.Add(2, new Enemy(200));
}
public Enemy GetEnemy(int num)
{
return EnemyList[num] as Enemy;
}
}
4.使用該工廠,通過傳遞顏色資訊來獲取實體類的物件
class Program
{
static void Main(string[] args)
{
FactoyEnemy factoryEnemy = new FactoyEnemy();
Enemy enemy = factoryEnemy.GetEnemy(1);
Console.WriteLine(enemy.ToString());
enemy = factoryEnemy.GetEnemy(2);
Console.WriteLine(enemy.ToString());
Console.ReadKey();
}
}
整合後的程式碼:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace 享元模式
{
public abstract class AbEnemy
{
public string color;
public int x;
public int y;
public AbEnemy()
{
color = "紅";
x = 100;
}
public override string ToString()
{
return string.Format("生成{0}顏色的敵人,位置在X為{1},Y為{2}", color, x, y);
}
}
public class Enemy:AbEnemy
{
public Enemy(int posY)
{
y = posY;
}
}
public class FactoyEnemy
{
private Dictionary<int, Enemy> EnemyList;
public FactoyEnemy()
{
EnemyList = new Dictionary<int, Enemy>();
EnemyList.Add(1, new Enemy(100));
EnemyList.Add(2, new Enemy(200));
}
public Enemy GetEnemy(int num)
{
return EnemyList[num] as Enemy;
}
}
class Program
{
static void Main(string[] args)
{
FactoyEnemy factoryEnemy = new FactoyEnemy();
Enemy enemy = factoryEnemy.GetEnemy(1);
Console.WriteLine(enemy.ToString());
enemy = factoryEnemy.GetEnemy(2);
Console.WriteLine(enemy.ToString());
Console.ReadKey();
}
}
}
優缺點
優點:
大大減少物件的建立,降低系統的記憶體,使效率提高。
缺點:
提高了系統的複雜度,需要分離出外部狀態和內部狀態,而且外部狀態具有固有化的性質,不應該隨著內部狀態的變化而變化,否則會造成系統的混亂。
總結
使用場景:
1、一個系統中有大量的物件;
2、這些物件耗費大量的記憶體;
3、這些物件中的狀態大部分都可以被外部化;
4、這些物件可以按照內部狀態分成很多的組,當把外部物件從物件中剔除時,每一個組都可以僅用一個物件代替;
5、軟體系統不依賴這些物件的身份。