您的位置:首页 > 其它

享元模式

2016-04-08 16:13 218 查看
原理:

     运用共享技术有效地支持大量细粒度的对象。

不使用享元模式:

class Game  //游戏
{
private string name = "";
public Game(string name)
{
this.name = name;
}

public void Play()
{
Console.WriteLine("运行游戏:" + name);
}
}

static void Main(string[] args)
{
Game zs = new Game("斗地主");
zs.Play();

Game ls = new Game("斗地主");
ls.Play();

Game ww = new Game("斗地主");
ww.Play();

Game zl = new Game("麻将");
zl.Play();

Game sq = new Game("麻将");
sq.Play();

Game zb = new Game("麻将");
zb.Play();

Console.Read();
}
三个斗地主实例,本质都是一样的代码,但是随着用户增多,实例也会增多,对服务器资源造成浪费,希望共享代码



abstract class Game   //游戏
{
public abstract void Play();
}

//具体的游戏
class ConcreteGame : Game
{
private string name = "";
public ConcreteGame(string name)
{
this.name = name;
}

public override void Play()
{
Console.WriteLine("运行游戏:" + name);
}
}
class GameFactory   //游戏工厂
{
private Hashtable flyweights = new Hashtable();

//获得游戏分类
public Game GetGameCategory(string key)
{
if (!flyweights.ContainsKey(key))
flyweights.Add(key, new ConcreteGame(key));
return ((Game)flyweights[key]);
}

//获得游戏分类总数
public int GetGameCount()
{
return flyweights.Count;
}
}
static void Main(string[] args)
{

GameFactory f = new GameFactory();

Game zs = f.GetGameCategory("斗地主");
zs.Play();
Game ls = f.GetGameCategory("斗地主");
ls.Play();
Game ww = f.GetGameCategory("斗地主");
ww.Play();
Game zl = f.GetGameCategory("麻将");
zl.Play();
Game sq = f.GetGameCategory("麻将");
sq.Play();
Game zb = f.GetGameCategory("麻将");
zb.Play();
Console.WriteLine("游戏逻辑总数为 {0}", f.GetGameCount());

Console.Read();
}


内部状态与外部状态

(1)上述代码实现了享元模式共享的目的,无论几个用户,运行游戏一样,就只保留一个游戏逻辑代码。

(2)但是,这些用户毕竟不是同一个用户,用户名不同,用户的牌也不同。
(3)我们称享元对象内部不随环境变化的共享部分称为内部状态。

(4)而随环境而改变,不可以共享的称为外部状态。



//用户
public class User
{
private string name;

public User(string name)
{
this.name = name;
}

public string Name
{
get { return name; }
}
}

abstract class Game   //游戏
{
public abstract void Play(User user);
}

//具体的游戏
class ConcreteGame : Game
{
private string name = "";
public ConcreteGame(string name)
{
this.name = name;
}

public override void Play(User user)
{
Console.WriteLine("运行游戏:" + name + " 用户:" + user.Name);
}
}
static void Main(string[] args)
{
GameFactory f = new GameFactory();

Game zs = f.GetGameCategory("斗地主");
zs.Play(new User("张三"));
Game ls = f.GetGameCategory("斗地主");
ls.Play(new User("李四"));
Game ww = f.GetGameCategory("斗地主");
ww.Play(new User("王五"));
Game zl = f.GetGameCategory("麻将");
zl.Play(new User("赵六"));
Game sq = f.GetGameCategory("麻将");
sq.Play(new User("孙七"));
Game zb = f.GetGameCategory("麻将");
zb.Play(new User("周八"));

Console.WriteLine("游戏逻辑总数为 {0}", f.GetGameCount());

Console.Read();
}
优缺点:

享元模式的优点在于它大幅度地降低内存中对象的数量。但是,它做到这一点所付出的代价也是很高的,享元模式使得系统更加复杂。 

为了使对象可以共享,需要将一些状态外部化,这使得程序的逻辑复杂化。

应用:

享元模式在编辑器软件中大量使用,如在一个文档中多次出现相同的图片,则只需要创建一个图片对象,通过在应用程序中设置该图片出现的位置,可以实现该图片在不同地方多次重复显示。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: