码迷,mamicode.com
首页 > Windows程序 > 详细

C#面向对象设计之——享元模式(十二)

时间:2015-09-25 18:08:23      阅读:273      评论:0      收藏:0      [点我收藏+]

标签:

一、前言

运用共享模式能够有效地支持大量细粒度的对象。

二、结构图

技术分享

三、实例代码

namespace 享元模式
{
    class Program
    {
        static void Main(string[] args)
        {
            int extrinsicstate = 22;

            FlyweightFactory f = new FlyweightFactory();

            Flyweight fx = f.GetFlyweight("X");
            fx.Operation(--extrinsicstate);     //   --extrinsicstate    减去1再传入

            Flyweight fy = f.GetFlyweight("Y");
            fy.Operation(--extrinsicstate);

            Flyweight fz = f.GetFlyweight("Z");
            fz.Operation(--extrinsicstate);

            UnsharedConcreteFlyweight uf = new UnsharedConcreteFlyweight();

            uf.Operation(--extrinsicstate);

            Console.Read();
        }
    }

    class FlyweightFactory
    {
        private Hashtable flyweights = new Hashtable();

        public FlyweightFactory()
        {
            flyweights.Add("X", new ConcreteFlyweight());
            flyweights.Add("Y", new ConcreteFlyweight());
            flyweights.Add("Z", new ConcreteFlyweight());

        }

        public Flyweight GetFlyweight(string key)
        {
            return ((Flyweight)flyweights[key]);
        }
    }

    abstract class Flyweight
    {
        public abstract void Operation(int extrinsicstate);
    }

    class ConcreteFlyweight : Flyweight
    {
        public override void Operation(int extrinsicstate)
        {
            Console.WriteLine("具体Flyweight:" + extrinsicstate);
        }
    }

    class UnsharedConcreteFlyweight : Flyweight
    {
        public override void Operation(int extrinsicstate)
        {
            Console.WriteLine("不共享的具体Flyweight:" + extrinsicstate);
        }
    }
}

四、总结

享元对象内部不会随着环境的改变而改变的共享部分可以成为享元对象的内部状态,而随着环境改变而改变的,不可以共享的状态就是外部状态了。事实上,享元模式可以避免大量的非常相似的开销,在程序设计中,有时需要生成大量细粒度的类实例来表示数据,如果发现这些实例除了几个参数不同外基本上是相同的,如果把这些参数移到类实例的外面,在方式调用时将它们传递进来,就可以通过共享大幅度减少单个实例的数目,也就是说享元模式Flyweight执行所需的状态是有内部的也有可能有外部的,内部状态存储于ConcreteFlyweight对象之中,而外部状态则应该考虑由客户端对象存储或计算,当调用Flyweight对象操作时,将该状态传递给它。
什么时候考虑使用享云模式呢?
如果一个应用程序使用了大量的对象,而大量的对象会造成很大的内存开销时就应该考虑使用,还有就是对象的大多数状态可以外部状态,如果删除对象的外部状态,那么可以用相对较少的共享对象取代很多组对象,此时可以考虑使用享元模式。
缺点:使用享云模式维护一个记录了系统已经有的所有享元列表,这本身也是需要耗费资源的,另外享云模式使得系统更加复杂化,为了使对象可以共享,需要将一些状态外部化,也使得程序的逻辑复杂化,因此,应当在有足够多的对象实例可共享时才值得使用享元模式。

五、另外的实例代码

namespace 享元模式
{
    public class Program
    {
        static void Main(string[] args)
        {
            GameFactory f = new GameFactory();
            AbsGame absGame1 = f.GetGame("围棋", "红色");



            AbsGame absGame2 = f.GetGame("围棋", "红色");

            AbsGame absGame3 = f.GetGame("围棋", "红色");

            AbsGame absGame4 = f.GetGame("围棋", "白色");

            AbsGame absGame5 = f.GetGame("围棋", "白色");

            AbsGame absGame6 = f.GetGame("飞机棋", "红色");
            AbsGame absGame7 = f.GetGame("飞机棋", "红色");
            AbsGame absGame8 = f.GetGame("飞机棋", "红色");
            AbsGame absGame9 = f.GetGame("飞机棋", "白色");
            AbsGame absGame10 = f.GetGame("飞机棋", "白色");
            AbsGame absGame11 = f.GetGame("飞机棋", "黄色");
            AbsGame absGame12 = f.GetGame("飞机棋", "蓝色");

            f.CountGame();

            absGame1.Show(1);
            absGame2.Show(2);
            absGame3.Show(3);
            absGame4.Show(4);
            absGame5.Show(5);
            absGame6.Show(6);
            absGame7.Show(7);
            absGame8.Show(8);
            absGame9.Show(9);
            absGame10.Show(10);
            absGame11.Show(11);
            absGame12.Show(12);


            Console.WriteLine("------------------------围棋2种棋子啦啦啦啦啦啦----------------");

            Console.WriteLine("------------------------飞机棋4种棋子啦啦啦啦啦啦----------------");

            absGame1.GetChess("红色").Color();
            absGame4.GetChess("白色").Color();

            absGame5.GetChess("红色").Color();




            Console.WriteLine("围棋的棋子实例个数=" + ((Game)absGame3).htChess.Count);

            Console.WriteLine("飞机棋的棋子实例个数=" + ((Game)absGame10).htChess.Count);

            //absGame3.CountChess();
            //absGame10.CountChess();

            Console.ReadKey();

        }
    }



    public class GameFactory
    {
        public Hashtable htGame = new Hashtable();

        public AbsGame GetGame(string gameName, string color)
        {

            if (((Game)htGame[gameName]) == null)
            {
                htGame.Add(gameName, new Game(gameName, color));
            }

            if ((htGame.ContainsKey(gameName)) && !((Game)htGame[gameName]).htChess.ContainsKey(color))
            {
                ((Game)htGame[gameName]).GetChess(color);
            }
            return (Game)htGame[gameName];
        }

        public void CountGame()
        {
            Console.WriteLine("一共有" + htGame.Count + "个游戏对象");
        }

    }


    public abstract class AbsGame
    {
        public abstract void Show(int index);
        public abstract AbsChess GetChess(string color);
        public abstract void CountChess();
    }

    public class Game : AbsGame
    {

        public string GameName;

        public Hashtable htChess = new Hashtable();

        public Game(string gameName, string color)
        {

            GameName = gameName;
            GetChess(color);
        }

        public override AbsChess GetChess(string color)
        {
            if (!htChess.ContainsKey(color))
            {
                htChess.Add(color, new Chess(color));
            }
            return (Chess)htChess[color];
        }



        public override void Show(int index)
        {
            Console.WriteLine("游戏名:" + GameName + ",下棋位置:" + index);
        }

        public override void CountChess()
        {
            Console.WriteLine("一共有" + htChess.Count + "个棋子对象");
        }




    }



    public abstract class AbsChess
    {

        public abstract void Color();
    }


    public class Chess : AbsChess
    {
        private string color;
        public Chess(string color)
        {
            this.color = color;
        }
        public override void Color()
        {
            Console.WriteLine("这是" + color + "棋子");
        }
    }
}

 

C#面向对象设计之——享元模式(十二)

标签:

原文地址:http://www.cnblogs.com/kesimin/p/4838620.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!