前言:为什么要用享元模式
因为当一个系统中含有很多相似的对象时,如果每个对象都要占内存的话,那么对系统的性能是有影响的,此时如果将相似对象的共同部分作为一个共同的对象,不同的部分再通过方法传入不同的参数来实现的话,这样就能节省很多内存,代码如下:
一、单纯享元模式
1、抽象享元类
该类除了定义抽象方法用实现相似对象的共同功能,还要定义一个外部方法用于传入外部参数,从而组成不同的相似对象

 abstract class AbstractCom//抽象享元类
    {

        protected abstract void Operation();//抽象方法,设置颜色
        public void Display(Pos pos)//外部方法,并且要传入参数
        {
            this.Operation();
            Console.WriteLine($"我的位置是x:{pos.X },y:{pos.Y }");
        }
    }

2、具体享元类
用于实现抽象享元类中的抽象方法

 class BlackPiece : AbstractCom//具体享元类1
    {
        protected override void Operation()
        {
            Console.WriteLine("我是黑棋");
        }
    }
  class WhitePiece : AbstractCom//具体享元类2
    {
        protected override void Operation()
        {
            Console.WriteLine("我是白棋");
        }
    }

3、外部参数,用于记录相似对象的不同部分

 class Pos//外部参数
    {
        public int X { get; set; }
        public int Y { get; set; }
    }

4、工厂类
工厂类用于获取对象,根据键获取对象

 class ComFactory//工厂类,创建唯一对象
    {
        private ComFactory()//防止实例化,只允许通过静态类获取唯一实例
        {

        }
        private static ComFactory instance = new ComFactory();
        Hashtable hashtable = new Hashtable();//存储享元对象
        public static ComFactory GetInstance()
        {
            return instance;
        }
        public AbstractCom GetComObj(string key)//获取享元对象
        {
            if (hashtable.ContainsKey(key))//有对象就直接返回
            {
                return (AbstractCom)hashtable[key];
            }
            else//无对象,根据键来创建对象
            {
                if (key == "黑")
                {
                    AbstractCom abstractCom = new BlackPiece();
                    hashtable.Add(key, abstractCom);
                    return abstractCom;
                }
                else if (key == "白")
                {
                    AbstractCom abstractCom = new WhitePiece();
                    hashtable.Add(key, abstractCom);
                    return abstractCom;
                }
                else
                {
                    return null;
                }

            }
        }

    }

调用:

 ComFactory comFactory = ComFactory.GetInstance();

            AbstractCom abstraction1 = comFactory.GetComObj("黑");
            AbstractCom abstraction2 = comFactory.GetComObj("黑");

            AbstractCom abstraction3 = comFactory.GetComObj("白");
            AbstractCom abstraction4 = comFactory.GetComObj("白");


            abstraction1.Display(new Pos() { X =10,Y =200});
            abstraction2.Display(new Pos() { X = 0, Y = 0 });
            abstraction3.Display(new Pos() { X = 0, Y = 0 });
            abstraction4.Display(new Pos() { X = 0, Y = 0 });

           
            Console.WriteLine($"{abstraction1 ==abstraction2}");
            Console.WriteLine($"{abstraction3 == abstraction4}");

输出:

我是黑棋
我的位置是x:10,y:200
我是黑棋
我的位置是x:0,y:0
我是白棋
我的位置是x:0,y:0
我是白棋
我的位置是x:0,y:0
True
True

通过输出可以看出abstraction1和abstraction2 是同一个对象,abstraction3和abstraction4也是同一个对象,虽然他们通过外部参数实现了不同的功能,但是因为是同一个对象所以节省了内存。

二、复合享元模式:

 abstract class AbstractCom//抽象享元类
    {
        public abstract void  Add(AbstractCom abstractCom);
        protected abstract void Operation();//抽象方法,设置颜色
        public void Display()//外部方法,并且要传入参数
        {
            this.Operation();
           
        }

    }

    class BlackPiece : AbstractCom//具体享元类1
    {
        protected override void Operation()
        {
            Console.WriteLine("我是黑棋");
        }
        public override void Add(AbstractCom abstractCom)
        {
            
        }
    }
    class WhitePiece : AbstractCom//具体享元类2
    {
        protected override void Operation()
        {
            Console.WriteLine("我是白棋");
        }
        public override void Add(AbstractCom abstractCom)
        {

        }
    }

    class PieceContainer:AbstractCom
    {
       List <AbstractCom>  _List = new List<AbstractCom> ();
        public override void Add(AbstractCom abstractCom)
        {
            _List.Add(abstractCom);
        }
        protected override void Operation()
        {
            Console.WriteLine("我是容器");
            foreach (AbstractCom item in _List)
            {
                item.Display();
            }
        }
    }
  class ComFactory//工厂类,创建唯一对象
    {
        private ComFactory()//防止实例化,只允许通过静态类获取唯一实例
        {

        }
        private static ComFactory instance = new ComFactory();
        Hashtable hashtable = new Hashtable();//存储享元对象
        public static ComFactory GetInstance()
        {
            return instance;
        }
        public AbstractCom GetComObj(string key)//获取享元对象
        {
            if (hashtable.ContainsKey(key))//有对象就直接返回
            {
                return (AbstractCom)hashtable[key];
            }
            else//无对象,根据键来创建对象
            {
                if (key == "黑")
                {
                    AbstractCom abstractCom = new BlackPiece();
                    hashtable.Add(key, abstractCom);
                    return abstractCom;
                }
                else if (key == "白")
                {
                    AbstractCom abstractCom = new WhitePiece();
                    hashtable.Add(key, abstractCom);
                    return abstractCom;
                }
                else
                {
                    return null;
                }

            }
        }

    }

调用:

ComFactory comFactory = ComFactory.GetInstance();




            AbstractCom abstraction1 = comFactory.GetComObj("黑");
            AbstractCom abstraction2 = comFactory.GetComObj("黑");

            AbstractCom container1 = new PieceContainer();
            container1.Add(abstraction1);
            container1.Add(abstraction2);

            AbstractCom container2 = new PieceContainer();
          
            AbstractCom abstraction3 = comFactory.GetComObj("白");
            AbstractCom abstraction4 = comFactory.GetComObj("白");
            container2.Add(abstraction3);
            container2.Add(abstraction4);
            container1.Add(container2);



            container1.Display();

更多推荐