享元模式

来源:互联网 发布:mac连接usb鼠标 编辑:程序博客网 时间:2024/06/06 03:02

原理:

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

不使用享元模式:

 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();        }
优缺点:

享元模式的优点在于它大幅度地降低内存中对象的数量。但是,它做到这一点所付出的代价也是很高的,享元模式使得系统更加复杂。 
为了使对象可以共享,需要将一些状态外部化,这使得程序的逻辑复杂化。


应用:

享元模式在编辑器软件中大量使用,如在一个文档中多次出现相同的图片,则只需要创建一个图片对象,通过在应用程序中设置该图片出现的位置,可以实现该图片在不同地方多次重复显示。

0 0