c#设计模式——享元模式

前言:为什么要用享元模式
因为当一个系统中含有很多相似的对象时,如果每个对象都要占内存的话,那么对系统的性能是有影响的,此时如果将相似对象的共同部分作为一个共同的对象,不同的部分再通过方法传入不同的参数来实现的话,这样就能节省很多内存,代码如下:
一、单纯享元模式
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();
  • 0
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
原型模式是一种创建型设计模式,其提供了一种复制已有对象的方法来生成新对象的能力,而不必通过实例化的方式来创建对象。原型模式是通过克隆(浅复制或深复制)已有对象来创建新对象的,从而可以避免对象创建时的复杂过程。 在C#中,可以通过实现ICloneable接口来实现原型模式。ICloneable接口定义了Clone方法,该方法用于复制当前对象并返回一个新对象。需要注意的是,Clone方法返回的是Object类型,需要进行强制类型转换才能得到复制后的对象。 以下是一个简单的示例代码: ```csharp public class Person : ICloneable { public string Name { get; set; } public int Age { get; set; } public object Clone() { return MemberwiseClone(); } } // 使用示例 var person1 = new Person { Name = "Tom", Age = 20 }; var person2 = (Person)person1.Clone(); person2.Name = "Jerry"; Console.WriteLine(person1.Name); // 输出 "Tom" Console.WriteLine(person2.Name); // 输出 "Jerry" ``` 在上面的示例代码中,实现了一个Person类,并实现了ICloneable接口中的Clone方法来实现原型模式。复制对象时,使用MemberwiseClone方法进行浅复制,即只复制值类型的字段和引用类型字段的引用,而不复制引用类型字段所引用的对象。在使用示例中,首先创建一个Person对象person1,然后通过Clone方法复制一个新的对象person2,修改person2的Name属性后,输出person1和person2的Name属性,可以看到person1的Name属性并没有改变,说明person2是一个全新的对象。 需要注意的是,如果要实现深复制,即复制引用类型字段所引用的对象,需要在Clone方法中手动将引用类型字段复制一份。另外,使用原型模式时,需要注意复制后的对象和原对象之间的关系,如果复制后的对象修改了原对象的状态,可能会对系统产生意想不到的影响。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

c#上位机

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值