小看--享元模式

  (一)享元模式概述

     享元模式:从名字也可以看出享元,共享,这就是程序里面说的共享经济,官方说法就是:利用共享技术有效的支持大量细粒对象;简单的就是大对象共享吧,因为大对象创建耗时耗,耗资源。下面看一个最普通的例子,也是享元模式的经典应用,下面这个例子的输出的结果是什么?

 string testStr = "zhangzhen";
            string name = "zhangzhen";
            Console.WriteLine(testStr==name); //比较值
            Console.WriteLine(testStr.Equals(name));//比较值
            Console.WriteLine(Object.ReferenceEquals(testStr,name));//比较引用

    大家从结果中,也可以发现字符串的恒等性,其实就是利用了享元模式的创建,不然内存中字符串得占多少内存。下面且听我详细的介绍字符串的是如何实现恒等性。

 

    一般对象都是按照上面这种创建方式,但是字符串呢,是不会这么干的,因为字符串这个对象在我们一个程序中,存在的实在太多了,所以语言的设计者们,就用了享元模式的思想。

    

   如上图所示,就是这样做到字符串的恒等性,也就是我们一开始那三个答案都是为true; 继续我们的思考,程序设计语言者们是如何利用享元模式做到字符串的恒等性呢。

 (二)享元模式的实现

    继续上面所说的,然后带着我们应该怎么做呢,怎么做到共享呢,我们应该建立一个HashSet来存放已有的对象,每次对象的创建的时候,都去判断一下是否存在HashSet里面,我们应该把对象放到缓存,然后再判断,还是啥的,等等各种想法

    带着上面的问题,我们来看接下来这个例子:

     

 

    一般的享元工厂类(这里是一个简单工厂)

public class FlyweightFactory
    {
        //对象共享
        private static Dictionary<WordType, BaseWord> _FlyweightFactoryDictionary = new Dictionary<WordType, BaseWord>();
        private static readonly object FlyweightFactoryLock = new object();

        public static BaseWord CreateWord(WordType wordType)
        {
            if (!_FlyweightFactoryDictionary.ContainsKey(wordType))//是在对象初始化之后,不再进去锁,保证多线程并发
            {
                lock (FlyweightFactoryLock)//保证只有一个线程能进入,其他的排队   就是变成单线程
                {
                    if (!_FlyweightFactoryDictionary.ContainsKey(wordType))//如果不存在,则创建并写入字典
                    {
                        BaseWord baseWord = null;
                        switch (wordType)
                        {
                            case WordType.A:
                                baseWord = new A();
                                break;
                            case WordType.B:
                                baseWord = new B();
                                break;
                            case WordType.C:
                                baseWord = new C();
                                break;
                            default:
                                throw new Exception("wrong wordType");
                        }
                        _FlyweightFactoryDictionary[wordType] = baseWord;
                    }
                }
            }
            return _FlyweightFactoryDictionary[wordType];
        }

        public enum WordType
        {
            A,
            B,
            C,
        }

  享元工厂主要是为了解决对象的重用问题(大对象),减少频繁的创建和销毁。但是它不是属于那种强制性的,它的思想值得我们学习,也行我们不一定非要为了享元而享元。

 

    

 

    

 

posted @ 2018-01-21 20:11  GDOUJKZZ  阅读(179)  评论(0编辑  收藏  举报